解密C++(一)继承属性

解密c++特性下的继承属性

  • 继承方式

常见地,在抽象一个c++类的时候,通常需要加入访问限定符,一般的,将成员变量定义为私有,成员函数作为公有,成员函数则成为外部访问私有成员变量的一个接口

如果发现一个类中没有明确指定访问限定符,class一般默认访问限定为private私有   而在struct中一般默认访问限定为public公有

具体的继承方式及访问限定如下图

其中,私有成员在类外不可访问,只有类内部可访问,除非定义为该类的友元函数

如果想让基类的成员仅在派生类中依然可访问,但在类外不可访问,可以将其定义为protect成员

除基类的私有成员在子类中是不可见的,其余基类成员在子类中额访问方式为:min(继承方式,访问限定符)

  • 继承赋值

派生类对象可以赋值给基类对象,指针或引用      派生类由于继承的关系,比基类大,所以赋值过程类似于一个切片过程

反过来,基类对象不能给派生类对象赋值,   派生类的一部分成员在基类中不存在  无法完成赋值

  • 继承的作用域

子类和父类中存在同名函数,则构成隐藏,子类成员将屏蔽父类对同名成员函数的访问,此时只会访问父类同名函数,除非通过类名::同名函数  显示调用

注意:只要函数名相同,便会形成隐藏,对此在继承过程中,尽量避免同名函数

  • 派生类的默认成员函数

  1. 派生类的构造函数必须调用基类的构造函数初始化基类部分成员,如果基类中没有默认的构造函数,则必须在子类构造函数初始化列表中进行初始化 
  2. 如果子类采用默认构造函数,编译器会调用父类的默认构造函数,如果父类不存在默认构造则报错返回
  3. 派生类的拷贝构造函数必须通过调用基类拷贝构造函数完成基类拷贝初始化,派生类构造函数初始化列表可以采用父类构造函数或父类拷贝构造函数切片操作
  4. 派生类构造函数和析构函数的调用顺序如下图:

  • 虚拟继承

存在以下菱形继承关系

根据代码测试各个类大小发现,菱形继承下,存在数据冗余情况,以及二义性

class A
{
public:
    int _a;
};
// class B : public A
class B : virtual public A
{
public:
    int _b;
};
// class C : public A
class C : virtual public A
{
public:
    int _c;
};
class D : public B, public C
{
public:
    int _d;
};
int main()
{
    D d;
    d.B::_a = 1;
    d.C::_a = 2;
    d._b = 3;
    d._c = 4;
    d._d = 5;
    return 0;
}

这里可以分析出D对象中将A放到的了对象组成的最下面,这个A同时属于B和C,那么B和C如何去找到公共的A呢?

这里是通过了B和C的两个指针,指向的一张表。这两个指针叫虚基表指针,这两个表叫虚基表。虚基表中存的偏移量。通过偏移量可以找到下面的A

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HT . WANG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值