c++继承全讲解

一、C++中的对象模型

1、 概念

语言中直接支持面向对象程序设计的部分;

对于各种支持的底层实现机制。(没看懂……)

2、 类中的成员分类

a) 成员函数

  i. static function

  ii. non static function

  iii. virtual function

b)  数据成员

  i. static member data

  ii. non static member data

3、 C++对象模型

a) 类对象内存布局中的包括

  i. non static member data

  ii. vptr(虚函数表指针)

  iii. vbptr(虚基类表指针)

b) 不包括

  i. static member data(存储在静态存储区)

  ii. 成员函数(存储在代码区)

c) virtual table

简称vtbl。存放着指针,这些指针指向该类每一个虚函数。虚表中的函数地址将按声明时的顺序排列。vtbl在类声明后就形成了,vptr是编译器生成的。

d) vptr的位置一般放在一个类对象的最前端。

e) 虚基类表

vbptr指向的表,用于存放虚继承中,虚基类存储相对于虚基类表指针的偏移量。

c++继承全讲解

二、继承类型

1、普通继承(不包含虚函数)

a、单继承

复制代码
class Base
{
public:
    Base (int a = 1):base(a){}
    void fun0(){cout << base << endl;}
    int base;
};
class Derive:public Base
{
public:
    Derive (int a = 2):derive(a){}
    void fun1(){cout << base1 << endl;}
    int derive;
};
复制代码

c++继承全讲解

b、多继承

复制代码
class Base1
{
public:
    Base1 (int a = 2):base1(a){}
    void fun1(){cout << base1 << endl;}
    int base1;
};
class Base2
{
public:
    Base2 (int a = 3):base2(a){}
    void fun2(){cout << base2 << endl;}
    int base2;
};
class Derive: public Base1, public Base2
{
public:
    Derive (int value = 4):derive (value){}
    void fun3(){cout << derive << endl;}
    int derive;
};
复制代码

c++继承全讲解

c、菱形继承

复制代码
class Base
{
public:
    Base (int a = 1):base(a){}
    void fun0(){cout << base << endl;}
    int base;
};
class Base1:public Base
{
public:
    Base1 (int a = 2):base1(a){}
    void fun1(){cout << base1 << endl;}
    int base1;
};
class Base2:public Base
{
public:
    Base2 (int a = 3):base2(a){}
    void fun2(){cout << base2 << endl;}
    int base2;
};
class Derive: public Base1, public Base2
{
public:
    Derive (int value = 4):derive (value){}
    void fun3(){cout << derive << endl;}
    int derive;
};
复制代码

c++继承全讲解

 

注:菱形继承存在二义性问题,编译都不通过,只能通过指定特定基类的方式进行访问基类变量。

Derive d;

       d.base =3; // 不正确

       d.Base1::base = 3; // 正确

2、普通继承(包含虚函数)

  a、单继承(包含虚函数)

复制代码
class Base
{
public:
    Base (int a = 1):base(a){}
    virtual void fun0(){cout << base << endl;}
    int base;
};
class Derive:public Base
{
public:
    Derive (int a = 2):derive(a){}
    virtual void fun0(){};
    virtual void fun1(){cout << derive << endl;}
    int derive;
};
复制代码

c++继承全讲解

注:派生类中新增的虚函数追加到虚函数表后面。

b、多继承(包含虚函数)

复制代码
class Base1
{
public:
    Base1 (int a = 2):base1(a){}
    virtual void fun1(){cout << base1 << endl;}
    int base1;
};
class Base2
{
public:
    Base2 (int a = 3):base2(a){}
    virtual void fun2(){cout << base2 << endl;}
    int base2;
};
class Derive: public Base1, public Base2
{
public:
    Derive (int value = 4):derive (value){}
    virtual void fun3(){cout << derive << endl;}
    int derive;
};
复制代码

c++继承全讲解

注:派生类中新增的虚函数,追加到第一个基类的虚函数表的后面。

       c、菱形继承(包含虚函数)

复制代码
class Base
{
public:
    Base (int a = 1):base(a){}
    virtual void fun0(){cout << base << endl;}
    int base;
};
class Base1:public Base
{
public:
    Base1 (int a = 2):base1(a){}
    virtual void fun1(){cout << base1 << endl;}
    int base1;
};
class Base2:public Base
{
public:
    Base2 (int a = 3):base2(a){}
    virtual void fun2(){cout << base2 << endl;}
    int base2;
};
class Derive: public Base1, public Base2
{
public:
    Derive (int value = 4):derive (value){}
    virtual void fun3(){cout << derive << endl;}
    int derive;
};
复制代码

c++继承全讲解

注:分析时,由上到下依次分析。存在二义性问题和内存冗余问题。

 3、虚继承(不包含虚函数)

新增虚基类指针,指向虚基类表,虚基类表中首项存储虚基类指针的偏移量,接下来依次存储虚基类的偏移量(偏移量是相对于虚基类表指针的存储地址)。

   a、单虚继承(不包含虚函数)

复制代码
class Base
{
public:
    Base (int a = 1):base(a){}
    void fun0(){cout << base << endl;}
    int base;
};
class Base1:virtual public Base
{
public:
    Base1 (int a = 2):base1(a){}
    void fun1(){cout << base1 << endl;}
    int base1;
};
复制代码

c++继承全讲解

   b、多虚继承(不包含虚函数)

复制代码
class Base1
{
public:
    Base1 (int a = 2):base1(a){}
    void fun1(){cout << base1 << endl;}
    int base1;
};
class Base2
{
public:
    Base2 (int a = 3):base2(a){}
    void fun2(){cout << base2 << endl;}
    int base2;
};
class Derive:virtual public Base1, virtual public Base2
{
public:
    Derive (int value = 4):derive (value){}
    void fun3(){cout << derive << endl;}
    int derive;
};
复制代码

c++继承全讲解

  c、菱形虚继承(不包含虚函数)

   第一种形式:

复制代码
class Base
{
public:
    Base (int a = 1):base(a){}
    void fun0(){cout << base << endl;}
    int base;
};
class Base1:virtual Base
{
public:
    Base1 (int a = 2):base1(a){}
    void fun1(){cout << base1 << endl;}
    int base1;
};
class Base2:virtual Base
{
public:
    Base2 (int a = 3):base2(a){}
    void fun2(){cout << base2 << endl;}
    int base2;
};
class Derive:virtual public Base1, virtual public Base2
{
public:
    Derive (int value = 4):derive (value){}
    void fun3(){cout << derive << endl;}
    int derive;
};
复制代码

c++继承全讲解

 

注:分析派生类的内存分布时,也是由上到下分析。虚继承将基类置于内存末尾,但是置于末尾的顺序也有一定的次序。首先Base先放到末尾,然后Base1放到末尾,最后Base2放到末尾。

       第二种形式:

复制代码
class Base
{
public:
    Base (int a = 1):base(a){}
    void fun0(){cout << base << endl;}
    int base;
};
class Base1:virtual public Base
{
public:
    Base1 (int a = 2):base1(a){}
    void fun1(){cout << base1 << endl;}
    int base1;
};

class Base2:virtual public Base
{
public:
    Base2 (int a = 3):base2(a){}
    void fun2(){cout << base2 << endl;}
    int base2;
};
class Derive: public Base1, public Base2
{
public:
    Derive (int value = 4):derive (value){}
    void fun3(){cout << derive << endl;}
    int derive;
};
复制代码

c++继承全讲解

 

注:分析的原则,从上到下,依次分析。

4、 虚继承(包含虚函数)

a、单虚继承(包含虚函数)

复制代码
class Base
{
public:
    Base (int a = 1):base(a){}
    virtual void fun0(){cout << base << endl;}
    int base;
};
class Base1:virtual Base
{
public:
    Base1 (int a = 2):base1(a){}
    virtual void fun1(){cout << base1 << endl;}
    int base1;
};
复制代码

c++继承全讲解

  与普通的包含虚函数的单继承相比,派生类拥有自己的虚函数表以及虚函数表指针,而不是与基类共用一个虚函数表。注意虚函数表指针和虚基类表指针的存储顺序。

  b、多虚继承(包含虚函数)

复制代码
class Base1
{
public:
    Base1 (int a = 2):base1(a){}
    virtual void fun1(){cout << base1 << endl;}
    int base1;
};

class Base2
{
public:
    Base2 (int a = 3):base2(a){}
    virtual void fun2(){cout << base2 << endl;}
    int base2;
};
class Derive:virtual public Base1, virtual public Base2
{
public:
    Derive (int value = 4):derive (value){}
    virtual void fun3(){cout << derive << endl;}
    int derive;
};
复制代码

c++继承全讲解

c、菱形虚继承(包含虚函数)

       第一种形式:

复制代码
class Base
{
public:
    Base (int a = 1):base(a){}
    virtual void fun0(){cout << base << endl;}
    int base;
};
class Base1:virtual public Base
{
public:
    Base1 (int a = 2):base1(a){}
    virtual void fun1(){cout << base1 << endl;}
    int base1;
};

class Base2:virtual public Base
{
public:
    Base2 (int a = 3):base2(a){}
    virtual void fun2(){cout << base2 << endl;}
    int base2;
};
class Derive:  public Base1, public Base2
{
public:
    Derive (int value = 4):derive (value){}
    virtual void fun3(){cout << derive << endl;}
    int derive;
};
复制代码

c++继承全讲解

第二种形式:

复制代码
class Base
{
public:
    Base (int a = 1):base(a){}
    virtual void fun0(){cout << base << endl;}
    int base;
};
class Base1:virtual public Base
{
public:
    Base1 (int a = 2):base1(a){}
    virtual void fun1(){cout << base1 << endl;}
    int base1;
};

class Base2:virtual public Base
{
public:
    Base2 (int a = 3):base2(a){}
    virtual void fun2(){cout << base2 << endl;}
    int base2;
};
class Derive: virtual public Base1,virtual public Base2
{
public:
    Derive (int value = 4):derive (value){}
    virtual void fun3(){cout << derive << endl;}
    int derive;
};
复制代码

自行脑补C++类对象的内存结构……

 

原文链接: https://www.cnblogs.com/jdxn/p/12773219.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    c++继承全讲解

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/344273

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 上午2:36
下一篇 2023年3月2日 上午2:36

相关推荐