解密C++继承属性

Posted AllenSquirrel

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解密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

以上是关于解密C++继承属性的主要内容,如果未能解决你的问题,请参考以下文章

C++:面向对象设计的继承性的相关编程代码讲解

C++ VS代码爆红:不允许对不可访问的基类进行转换(子类继承父类时必须加上继承属性,比如public)

C++ VS代码爆红:不允许对不可访问的基类进行转换(子类继承父类时必须加上继承属性,比如public)

C++ VS代码爆红:不允许对不可访问的基类进行转换(子类继承父类时必须加上继承属性,比如public)

C++三大特性-继承

C++三大特性-继承