C++ 继承下(二篇文章学习继承所有知识点)
创始人
2025-05-28 09:10:44

5.继承与友元

友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员

//验证友元不能继承
class B
{friend void Print();
public:B(int b): _b(b){cout << "B()" << endl;}protected:int _b;
};class D : public B
{
public:D(int b, int d): B(b), _d(_d){cout << "D(int,int)" << endl;}protected:int _d;
};void Print()
{B b(1);cout << b._b << endl;//结论:友元关系不能被继承//创建一个子类对象,如果子类对象D中的_d不能被访问,说明友元不能被继承D d(1, 2);//cout << d._d << endl;   编译失败
}

6. 继承与静态成员

基类定义了static静态成员,则整个继承体系里面只有一个这样的成员。无论派生出多少个子类,都只有一个static成员实例

// 静态成员可以被子类继承,并且在整个继承体系中只存在一份
class B
{
public:static int _b;
};int B::_b = 10;class D : public B
{
protected:int _d;
};class DD : public B
{
protected:int _d;
};int main()
{cout << D::_b << endl;cout << DD::_b << endl;cout << &B::_b << " " << &D::_b <<" "<<&DD::_b << endl;return 0;
}

地址一样,成功继承。说明静态成员可以被子类继承,并且在整个继承体系中只存在一份

7.不同继承方式下子类的对象模型

对象模型:对象中的成员在内存中的存储方式

单继承

一个子类只有一个直接父类时称这个继承关系为单继承

多继承

一个子类有两个或以上直接父类时称这个继承关系为多继承

注意:如果有多个基类,每个基类前必须要添加继承权限,否则就是默认的继承权限

菱形继承(钻石继承)

菱形继承是多继承的一种特殊情况

class B
{
public:int _b;
};class C1 : public B
{
public:int _c1;
};class C2 : public B
{
public:int _c2;
};class D : public C1,public C2
{
public:int _d;
};
int main()
{cout << sizeof(D) << endl;D d;return 0;
}

对上面代码进行如下操作:

菱形继承继承的二义性问题:

d._b = 1; // 编译失败:error C2385: 对“_b”的访问不明确

d.func(); // 编译失败:error C2385: 对“_b”的访问不明确

错误分析:

* D从C1中继承下来一个_b,从C2中也继承下来一个_b,导致D的模型中实际有2个_b

* 如果通过D的对象直接访问_b,编译器就不知道到底要访问从C1中继承下来的_b还是要访问

* 从C2中继承下来的_b

* 因此存在二义性

* 即:菱形继承的缺陷 因此:一般情况下尽量避免设计出菱形继承方式

菱形继承二义性问题解决方式:

1. 让访问明确化: 在成员前加类名以及作用域限定符

d.C1::_b = 1;

d._c1 = 2;

d.C2::_b = 3;

d._c2 = 4;

d._d = 5;

上述解决方式只是让代码通过编译了,但是最顶层基类中的成员在子类中仍旧是存在多份 /

不足:最顶层基类中的成员在子类中仍旧是存在多份,浪费空间,而且二义性并没有真正的解决

如果要真正解决,让最顶层类中的成员在子类(类型继承中最底下的类)只存储一份,在C++中引入了菱形虚拟继承解决上述问题

虚拟继承

虚拟继承可以解决菱形继承的二义性和数据冗余的问题。需要注意的是,虚拟继承不要在其他地方去使用

注意:平时在写继承的代码时,不会涉及虚拟继承的方式

虚拟继承只有一个作用:解决菱形继承二义性的问题

在继承权限前加上虚拟关键字即可

class B
{
public:int _b;
};class D : virtual public B
{
public:int _d;
};int main()
{cout << sizeof(D) << endl;   // 12, 普通继承是8D d;d._b = 1;d._d = 2;   // 直接一条mov指令搞定return 0;
}

利用菱形虚拟继承解决菱形继承中二义性问题

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

8.继承的总结和反思

1. C++语法复杂,其实多继承就是一个体现。有了多继承,就存在菱形继承,有了菱

形继承就有菱形虚拟继承,底层实现就很复杂。所以一般不建议设计出多继承,一定不要设

计出菱形继承。否则在复杂度及性能上都有问题。

2. 多继承可以认为是C++的缺陷之一,很多后来的OO语言都没有多继承,如Java。

3. 继承和组合

public继承是一种is-a的关系。也就是说每个派生类对象都是一个基类对象。

组合是一种has-a的关系。假设B组合了A,每个B对象中都有一个A对象

相关内容

热门资讯

霸气十足的近义词是什么 ,霸气... 霸气十足的近义词是什么 目录霸气十足的近义词是什么 霸气十足的近义词是什么?什么什么十足的成语霸气十...
经营类别是指什么 ,药品批发经... 经营类别是指什么 目录经营类别是指什么 药品批发经营类别是指什么增值税经营类别未分类 怎么分类企业经...
樱花动漫为什么没有莉可丽丝 ,... 樱花动漫为什么没有莉可丽丝 目录莉可丽丝漫画在哪里看樱花庄的宠物女孩为什么不出第二季莉可丽丝为什么烂...
什么是管理幅度 ,管理宽度指的... 什么是管理幅度 目录什么是管理幅度 管理宽度指的是什么?什么是管理幅度?什么是管理幅度?什么是管理幅...
预约有礼 | 迅镭激光与您相约...   3月29日-4月1日,国内机床工业领域第一场超大型专业展会——2023ITES深圳...
js正则:input 输入限制 这里写自定义目录标题正则:input 输入限制(IP和数值类型规则限制输...
再学C语言45:字符串输入 若需把一个字符串读到程序中,首先预留存储字符串的空间,然后使用输入函数获...
春联上联是一二声还是三四声 ,... 春联上联是一二声还是三四声 目录春联上联是一二声还是三四声 春联的帖法 有说三四声在左 ,有的说一二...
212事件是什么 ,212事件... 212事件是什么 目录我想问一下212事件什么梗212事件是什么QQ空间212事件是什么?腾讯回应"...
白清灵端王妃小说叫什么名字,女... 白清灵端王妃小说叫什么名字目录白清灵端王妃小说叫什么名字女军医穿越当王妃的叫白清灵的?莫凛程忆这本书...
有关军二代的小说介绍几个啊,求... 有关军二代的小说介绍几个啊目录有关军二代的小说介绍几个啊求男主是军二代或者是男主重生成军二代的小说,...
JVM参数的分类及常用参数 常用JVM参数 JVM参数可以分为三种类型,分别是以-、-X、-XX开头的参数 -开头的参数比较稳定...
Revit中屋面瓦填充图案问题...   一、Revit中屋面瓦填充图案无法随图案着屋面坡度方向的改变而改变   Revit中࿰...
求一本邪恶类的小说都市的,有什... 求一本邪恶类的小说都市的目录找个都市系统流小说,主角奇遇获得系统,要做任务,任务都很邪恶很变态的。有...
宫锁珠帘结局 ,《宫锁珠帘》结... 宫锁珠帘结局 目录宫锁珠帘结局 《宫锁珠帘》结局是什么?宫锁珠帘结局是什么宫锁珠帘结局如何 结局怜儿...
叶良辰是什么梗,一夜爆红网络,... 叶良辰是什么梗目录叶良辰是什么梗一夜爆红网络,叶良辰是个什么梗叶良辰是什么梗?叶良辰是什么梗?叶良辰...
dnf爆裂的信徒什么难度出 ,... dnf爆裂的信徒什么难度出 目录dnf爆裂的信徒什么难度出 DNF爆裂的信徒套装问题跪求DNF70及...
Stable Diffusio... Stable Diffusion 是一种尖端的开源工具,用于从文本生成图像。 Stab...
Crypto、Cython、p... 1、Crypto可用于加密密码生成许可证,但不能直接pip安装,常见问题...
Ubuntu 系统实时查看CP... Ubuntu 系统实时查看CPU和GPU温度: 方式一:lm-senso...
python 类、对象、sel... 类: 类相当与一个模板。 类包括:类名、属性、方法(类里面...
撞奶怎么做,姜汁撞奶如何制作 ... 撞奶怎么做目录撞奶怎么做姜汁撞奶如何制作姜汁撞奶的作法?撞奶怎么做如果您想尝试制作撞奶,建议您参考相...
盛夏晚晴天大结局 ,盛夏晚晴天... 盛夏晚晴天大结局 目录盛夏晚晴天大结局 盛夏晚晴天结局是什么盛夏晚晴天明娇和谢创结局是什么盛夏晚晴天...
蜗居小贝结局,蜗居大结局小贝怎... 蜗居小贝结局目录蜗居小贝结局蜗居大结局小贝怎么了《蜗居》中小贝最后怎么了?蜗居小贝结局蜗居小贝结局首...
电影捉迷藏剧情介绍 ,捉迷藏的... 电影捉迷藏剧情介绍 目录电影捉迷藏剧情介绍 捉迷藏的结局是什么?有一部韩国电影,叫做捉迷藏,是真实事...
气象灾害预警信号及防御指南 来源:中国气象报社   发布时间:2007-06-21 一、台风预警信号...
JMeter压测文件上传接口和... 一、压测文件上传接口 新建测试计划,然后添加需要的元件。 1、添加HTTP信息头管理...
数学小课堂:库尔贝勒交叉熵(K... 文章目录 引言I 预备知识:置信度(Confidence Level)1.1 置信度的定义1.1 提...
浮萍居主的作品 ,浮萍居主的作... 浮萍居主的作品 目录浮萍居主的作品 浮萍居主的作品朔月房心哪里能看浮萍居主的作品 浮萍居主是一个网络...
林正英鬼片有哪些,l林正英的鬼... 林正英鬼片有哪些目录林正英鬼片有哪些l林正英的鬼片和僵尸片里一共有多少部?什么鬼片好看的最好是林正英...