c++继承(二)

一、友元函数的继承

友元函数不能被继承,就像爸爸的朋友不是你的朋友,如果要有友元函数,在子类重新定义一个。

二、静态成员的继承

静态成员的继承仍然是那个成员,普通成员的继承是不同的。

父类的静态成员属于当前类,也属于当前类的派生类。

三、单继承与多继承

1、单继承

一个子类只有一个直接父类

2、多继承

一个子类有两个或以上的直接父类

四、菱形继承

1、理解

如图 Assistant 就是一个菱形继承,显然如果不做特殊处理 Assistant 里面会有两份 Person 类中的成员,这就导致了数据冗余和二义性。

解决办法就是在菱形继承中父类被继承两次的地方进行虚继承virtual

被继承的 Person 类是虚基类。

2、剖析

(1)未用 virtual

cpp 复制代码
class A
{
public:
	int _a;
};

class B : public A
//class B : virtual public A
{
public:
	int _b;
	int _b1;
	int _b2;

};

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

int main()
{
	D d;
	d.B::_a = 1;
	d.C::_a = 2;

	//d._a = 0;
	d._b = 3;
	d._c = 4;
	d._d = 5;
}

上图就是典型的菱形继承且没有解决,这样在D类中我们发现两个_a是不一样的,要想使用必须指定类域,这就是数据冗余和二义性。

内存级理解:

明显的看到内存中D对象中的B,C存有不同的_a,这是不被允许的。

(2)用 virtual

cpp 复制代码
class A
{
public:
	int _a;
};

//class B : public A
class B : virtual public A
{
public:
	int _b;
	int _b1;
	int _b2;

};

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

int main()
{
	D d;
	d.B::_a = 1;
	d.C::_a = 2;

	d._a = 0;
	d._b = 3;
	d._c = 4;
	d._d = 5;
}

上图我们用虚继承解决了问题,此时类D中的_a是同一个_a,所以最后_a值应该是0

内存级理解:

首先B,C类中不再存有_a的值,而是用一个地址代替了,_a的值被放到了D对象的内存最下面,地址所指向的内容存放的是_a的值0,还有十六进制的偏移量,用来找到原内存中_a的存储位置。

这样就解决了问题。

(3)总结

a、存地址的偏移量是为了方便找到数据,方便切片。

b、虚继承的解决原理:把原来存父类成员的地方存地址,通过地址和偏移量找到唯一的父类成员。实现原来有几个类继承就有几份父类成员的数据冗余变成现在存几个地址和偏移量来找到内存中唯一的一份父类成员,解决了数据冗余和二义性。

c、对象的存储按声明顺序存储。

五、继承和组合

我们发现继承和组合都能复用之前的类,两者是相似的,在实践中两者也会一起使用。

cpp 复制代码
//父类
class A {};

//继承
class B : public A
{
    //直接继承,直接使用
};

//组合
class C
{
private:
    A _aa;  //创建 A 对象,使用成员及方法
}

|----|-------------------------------------------------------------------------|
| 方式 | 备注 |
| 继承 | is_a关系,白箱复用(在继承方式中,基类的 内部细节对子类可见 。继承一定程度破坏了基类的封装,基类的改变,对派生类有很大的影响)耦合度高。 |
| 组合 | has_a关系,黑箱复用(为对象的内部细节是不可见的)耦合度低。 |

优先使用组合,组合的耦合度低,代码维护性好。

相关推荐
橘猫云计算机设计14 分钟前
基于JavaWeb的二手图书交易系统(源码+lw+部署文档+讲解),源码可白嫖!
java·开发语言·前端·毕业设计·php
半桔15 分钟前
红黑树剖析
c语言·开发语言·数据结构·c++·后端·算法
江烽渔火23 分钟前
C++ 多态
开发语言·c++
今天_也很困31 分钟前
牛客2025年愚人节比赛
c++·算法
嘤国大力士32 分钟前
C++11&QT复习 (十)
java·c++·qt
Joe_Wang534 分钟前
[图论]拓扑排序
数据结构·c++·算法·leetcode·图论·拓扑排序
m0_4902406740 分钟前
软件自动化测试(1):python+selenium自动化测试环境搭建
开发语言·python·selenium
2401_858286111 小时前
CD21.【C++ Dev】类和对象(12) 流插入运算符的重载
开发语言·c++·算法·类和对象·运算符重载
上理考研周导师1 小时前
【虚拟仪器技术】Labview虚拟仪器技术应用教程习题参考答案[13页]
服务器·开发语言
郭涤生1 小时前
Chapter 5: The Standard Library (C++20)_《C++20Get the details》_notes
开发语言·c++·笔记·c++20