c++继承(单继承,多继承,菱形继承和虚继承)详解

原创 2017年07月21日 14:36:32

下面我将从继承实例(代码 )继承对象模型原理来分析继承。
单继承
模型
这里写图片描述
代码

class A
{
public:
    int _a;
};
class B:public A
{
public:
    int _b;
};
int main()
{
    B b;
    b._a = 0;
    b._b = 1;

    return 0;
}

代码分析:
这里写图片描述
多继承
模型
这里写图片描述

class A
{
public:
    int _a;
};
class B
{
public:
    int _b;
};
class C :public A, public B
{
public:
    int _c;
};
int main()
{
    C c;
    c._a = 0;
    c._b = 1;
    c._c = 2;

    return 0;
}

代码分析
这里写图片描述
多继承我们要注意一个问题:当继承列表发送变化时,那么我们的对象模型也将发生改变。
原则:继承列表先写谁,谁将在低地址。和谁的类在不在前面无关,只于几次列表有关
我将 class C :public A, public B换成class C :public B, public A那么c的对象模型将变成下面的格式
这里写图片描述
菱形继承
模型
这里写图片描述

class A
{
public:
    int _a;
};
class B:public A
{
public:
    int _b;
};
class C:public A
{
public:
    int _c;
};
class D:public B,public C
{
public:
    int _d;
};

int main()
{
    D d1;
    d1._a = 0;
    d1._b = 1;
    d1._c = 2;
    d1._d = 4;


    return 0;
}

代码将不能编译通过,提示
这里写图片描述
当屏蔽//d1._a = 0;后可以通过编译,但是我们将无法访问父类的成员。所以我们迫切需要解决它的办法。
我们仔细看看报的错误,访问对象不明确,于是我们可以通过下面的方法进行访问_a:

d1.B::_a = 3;
d1.C::_a = 0;

这样就可以通过编译了。
下面我们研究下它的对象模型
这里写图片描述
我们通过计算可以得到对象d1的大小为20字节。但是对于我们来说,查找基类的成员变得困难了,有没有一种方式来解决这个问题?
于是虚继承出现了,它解决了菱形继承访问父类成员出现的二义性问题
下面我们一起来看看它是怎么解决二义性问题的:
虚继承
虚继承就是在被继承的前面加上virtual关键字
它是菱形继承的一种改进,所以它的继承方式和菱形继承一样,只是对象模型有区别。

class A
{
public:
    int _a;
};
class B:virtual public A
{
public:
    int _b;
};
class C :virtual public A
{
public:
    int _c;
};
class D:public B,public C
{
public:
    int _d;
};

int main()
{
    D d1;
    cout << sizeof(d1) << endl;
    d1._a = 0;
    d1._b = 1;
    d1._c = 2;
    d1._d = 4;


    return 0;
}

这里写图片描述
加入虚继承后d1的大小变成24字节,因为C类和B类都多了一个相对于_a的偏移量,所以多了四个字节。虚继承只有一份父类的数据,但是他在别的类中增加了四个字节来获取基类成员相对于别的类的偏移量。这样就解决了在菱形继承的二义性问题,但是它也引入了,程序性能下降的问题,这里就不做详细的说明。

版权声明:本文为博主原创文章,未经博主允许不得转载。

继承:单继承、派生类成员的访问属性、多继承、菱形继承、虚继承,菱形虚拟继承

1,派生类的声明方式class Student { public: void display() { cout

c++中的单继承,多继承(此处着重讲菱形继承)的内存布局模型详解

最近正好复习到继承的相关部分,想着把自己所学的东西还是再次归纳整理一遍,那么接下来就简单地梳理一下关于继承的一些知识点。 切入正题,什么是继承?“继承是c++语言的一种重要机制,该机制自动地为一个类提...

C++在单继承、多继承、虚继承时,构造函数、复制构造函数、赋值操作符、析构函数的执行顺序和执行内容

一、本文目的与说明    1. 本文目的:理清在各种继承时,构造函数、复制构造函数、赋值操作符、析构函数的执行顺序和执行内容。    2. 说明:虽然复制构造函数属于构造函数的一种,有共同的地方,但是...

C++在单继承、多继承、虚继承时,复制构造函数。赋值构造函数、析构函数的执行顺序

一、本文目的与说明     1. 本文目的:理清在各种继承时,构造函数、复制构造函数、赋值操作符、析构函数的执行顺序和执行内容。     2. 说明:虽然复制构造函数属于构造函数的一种,有共同的地...

c++单继承、多继承、菱形继承内存布局(虚函数表结构)

单继承:只有一个基类和一个派生类 class Base { public: virtual void fun1() { cout "Base::func1()" ...

C++里的继承和多态(下)——单继承、多继承、菱形继承(含虚拟函数的继承)

1、带有虚函数的类 class Base { public:                  virtual void FunTest1()                 {      ...

C++ &继承(单继承.多继承.菱形(虚拟)继承)

1:分析菱形继承的问题。 2:剖析虚继承是怎么解决二义性和数据冗余的。 多继承:(一个子类有两个或者两个以上的直接父类) 菱形继承: #include usin...

c++之各种继承(单继承,多继承,菱形继承)

基本简介在c++语言中。,一个派生类可以从一个基类派生,也可以从多个基类派生。从一个基类派生的继承称为单继承,从多个基类派生的继承称为多继承。继承可以使代码得到复用,子类还可以在父类的基础上添加功能 ...

C++对象内存布局:单继承,多继承,虚继承

1. 一个简单的例子class A{ int a=1; char b=2;//内存对齐 char c=3;//内存对齐 }; A instance;1.1 内存分布 地址...

C++在单继承、多继承、虚继承时,构造函数、复制构造函数、赋值操作符、析构函数的执行顺序和执行内容

转载自:http://blog.csdn.net/daheiantian/article/details/6438782 一、本文目的与说明     1. 本文目的:理清在各种...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:c++继承(单继承,多继承,菱形继承和虚继承)详解
举报原因:
原因补充:

(最多只允许输入30个字)