C++基础之继承(十五)

一.继承的定义

当一个派生类继承一个基类时,需要在派生类的类派生列表中明确的指出它是从哪个基类继承而来的。类派生列表的形式如下:

class 派生类

: public/private/protected  基类

{

};

派生类生成的三个步骤:

  1. 吸收基类成员
  2. 修改基类成员
  3. 增加自己新成员

二.继承的局限

不管什么继承方式,下面这些基类特征是不能从基类继承下来的:

  1. 构造函数
  2. 析构函数
  3. 用户重载的operator new/delete运算符
  4. 用户重载的operator=运算符
  5. 友元关系

三.派生(继承)方式对基类成员的访问权限

继承方式有3种,分别是

  • public公有继承
  • protected保护性继承
  • private私有继承
继承方式基类成员访问权限在派生类中访问权限派生类(子类)对象访问
公有继承

public

protected

private

public

protected

private

可直接访问

不可直接访问

不可直接访问

保护继承

public

protected

private

protected

protected

不可直接访问

不可直接访问
私有继承

public

protected

private

private

private

不可直接访问

不可直接访问

其中在不声明继承方式时默认时private。私有继承只能被继承一代,因为在私有继承结束后所有的成员都变为私有了,也就不能在被继承了。

#include <iostream>

using std::cout;
using std::cin;
using std::endl;


class Point
{
private:
    int _ix;

public:
    int _iy;
    Point(int ix=0,int iy=0)
    :_ix(ix)
    ,_iy(iy)
    {
        cout<<"Point(int ix=0,int iy=0)"<<endl;
    }

    ~Point()
    {
        cout<<"~Point()"<<endl;
    }

    int getX() const
    {
        return _ix;
    }
};

class Point3D
:private Point
{
private:
    int _iz;

public:
    Point3D(int ix=0,int iy=0,int iz=0)
    :Point(ix,iy)
    ,_iz(iz)
    {
        cout<<"Point3D(int ix=0,int iy=0,int iz=0)"<<endl;
    }
    ~Point3D()
    {
        cout<<"~Point3D()"<<endl;
    }

    int getZ()const
    {
        return _iz;
    }

    void print() const
    {
        cout<<"ix ="<<getX()<<"iy ="<<_iy<<"iz ="<<_iz<<endl;
    }
};

class Point4D
:public Point3D
{
private:
    int _id;
public:
    Point4D(int x=0,int y=0,int z=0,int d=0)
    :Point3D(x,y,z)
    ,_id(d)
    {
        cout<<"Point4D(int x=0,int y=0,int z=0,int d=0)"<<endl;
    }

    ~Point4D()
    {
        cout<<"~Point4D()"<<endl;
    }

    void print()const
    {
        cout<<"_ix = "<<getX()<<endl<<"_iy = "<<_iy<<endl   //error
        <<"_iz = "<<getZ()<<endl<<"_id = "<<_id<<endl;
    }


};

int main()
{
    Point4D P(1,2,3,4);
    P.print();
    return 0;
}

应该将Point3D类继承Point的方式变为public/protected。

#include <iostream>

using std::cout;
using std::cin;
using std::endl;


class Point
{
private:
    int _ix;

public:
    int _iy;
    Point(int ix=0,int iy=0)
    :_ix(ix)
    ,_iy(iy)
    {
        cout<<"Point(int ix=0,int iy=0)"<<endl;
    }

    ~Point()
    {
        cout<<"~Point()"<<endl;
    }

    int getX() const
    {
        return _ix;
    }
};

class Point3D
:protected Point
{
private:
    int _iz;

public:
    Point3D(int ix=0,int iy=0,int iz=0)
    :Point(ix,iy)
    ,_iz(iz)
    {
        cout<<"Point3D(int ix=0,int iy=0,int iz=0)"<<endl;
    }
    ~Point3D()
    {
        cout<<"~Point3D()"<<endl;
    }

    int getZ()const
    {
        return _iz;
    }

    void print() const
    {
        cout<<"ix ="<<getX()<<"iy ="<<_iy<<"iz ="<<_iz<<endl;
    }
};

class Point4D
:public Point3D
{
private:
    int _id;
public:
    Point4D(int x=0,int y=0,int z=0,int d=0)
    :Point3D(x,y,z)
    ,_id(d)
    {
        cout<<"Point4D(int x=0,int y=0,int z=0,int d=0)"<<endl;
    }

    ~Point4D()
    {
        cout<<"~Point4D()"<<endl;
    }

    void print()const
    {
        cout<<"_ix = "<<getX()<<endl<<"_iy = "<<_iy<<endl   //error
        <<"_iz = "<<getZ()<<endl<<"_id = "<<_id<<endl;
    }


};

int main()
{
    Point4D P(1,2,3,4);
    P.print();
    return 0;
}

四.基类(父类)数据成员的初始化

        在创建派生类(子类)对象的时候,在调用派生类(子类)构造函数的基础上,会先调用基类(父类)的构造函数对吸收继承的成员初始化,然后在继续调用派生类(子类)的构造函数初始化。

        当创建派生类对象时,会调用派生类的构造函数,为了完成从基类吸收继承的数据成员初始化,如果在派生类初试化参数列表没有显示调用基类的构造函数编译器会自动调用基类的无参构造函数,若基类没有无参构造函数,那么程序就会报错。如果派生类需要调用有参构造函数,那么基类必须要有该构造函数。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值