我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C++的继承特性你了解吗

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C++的继承特性你了解吗

导语:

C++是对C语言的优化和改进,C++之所以优秀的点在于它的特性:抽象、封装、继承和多态。

本章总结继承的规则和特性,都是干货,与读者共同学习。

继承作用

代码的复用

子类继承父类,可以理解为,将父类的代码拷贝一份到子类中,达到子类可以调用父类方法的目的。

那为什么是可以理解而不是就是呢?

是因为有几个东西是不可以拷贝的,比如,父类的拷贝和析构方法,友元和静态成员。

友元关系是不能继承的,必须各是各的。

静态成员是在类外初始化的,从定义到程序运行结束都一直存在,不是属于某一个类的。所以也不能拷贝。

形成多态

继承在代码复用上的应用是广泛的,但在我看来,继承最大的作用在于可以形成多态,当发生一种行为时,不同的对象去调用就是不同的状态。

这在很大程度上体现了C++作为面向对象语言的设计性。

继承的结果

上面说到继承相当于将父类的代码拷贝到子类中,达到可以使用子类对象可以调用父类方法的目的,而具体子类可以调用父类的哪些方法,还需要看它的继承方式。

继承方式

公有继承

class student:public Person
{};

公有继承,父类的公有方法以公有的形式,私有以私有的形式,保护以保护的形式,拷贝给子类,私有成员/成员方法对子类是不可见的。也就是说从对象角度:子类可以调用父类的公有方法和保护方法从方法角度:子类可以通过调用父类的公有方法/保护方法转调用父类的私有方法。

保护继承

class student:protected Person
{};

保护继承,父类的公有方法以保护的形式,私有以私有的形式,保护以保护的形式,拷贝给子类,继承后,子类中父类的私有方法对子类不可见的。

从对象角度,可以调用父类保护方法。

从方法角度,可以通过调用父类保护方法转调用父类私有方法。

私有继承(默认继承)

class student: Person     //什么都不给,默认私有继承
{}; 
class student:private Person
{};

私有继承,父类的所有方法均以私有的形式拷贝给子类,所有的对子类都是不可见的。

从对象角度:不能调用父类的方法

从方法角度:也不能转调用。

什么都不能用,那私有继承有什么用?

它作用的场景就是,在当前继承体系或分支,终止父类再往下继承下去。

子类构造

根据继承的拷贝性质,我们知道子类中有父类的成分,所以在构造子类之前,需要先调用父类的构造方法,再调用子类的构造方法。

但要注意,这个构造,只是构造了一个对象(子类),不会构造出来一个父类对象。

在这里插入图片描述

赋值兼容规则/向上转换/内存切片

继承和多态体系中,深入理解了赋值兼容规则就很容易掌握了。

赋值兼容规则:

  • 子类对象可以直接给父类对象赋值
  • 子类对象的地址可以直接给父类对象指针赋值
  • 子类对象可以直接初始化父类对象的引用

代码:

int main()
{
	D d;
	Base b;
	b = d;           //子类对象给父类对象赋值
	Base* pb = &d;   //子类对象的地址给父类对象指针赋值
	Base& rb = d;    //子类对象初始化父类对象的引用
	return 0;
}

总结,都是子类给父类(所以是向上转换),那么能不能父类给子类呢?

要理解这点,一个内存图即可说明一切!

在这里插入图片描述

很容易看出来,子类比父类的类型多了一部分,但都是序列化的,子类自身成员之前的内存空间与父类是完全一致的,所以子类是可以将地址、引用和对象转给父类的。

但是要注意,使用父类接收之后,父类对象/指针/引用,只能观察到父类拥有的,不能观察到子类。

当然,当有朝一日我们需要对父类取地址,要取到整个子类地址的时候(向下转换),C++11的reinterpret_cast强制类型转换可以实现这种需求。

赋值兼容规则的应用不在这几行代码,更在理解上,多态的形成就是建立在赋值兼容规则基础上的。

多继承

以上讲解都是建立在单继承上的。

一个子类有两个或两个以上直接父类时,就称这个继承是多继承。

多继承需要记住的点就是:
	构造时,按顺序对父类进行构造,若有虚拟继承的父类,先构造虚拟继承的父类
	菱形继承的问题和解决

多继承是复杂的,效率不高的。主要体现在菱形继承。一个图快速了解菱形继承:

在这里插入图片描述

菱形继承的缺点在于,在效率的角度,它是数据冗余的;站在安全的角度,他是数据二义的。

虚拟继承

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

代码:

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;
}

B和C虚拟继承A,就可以使来自A的数据只有一份了。

内存分析:

虚拟继承后,多了四个字节存储A的数据了。

内存分布为:

在这里插入图片描述

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!      

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

C++的继承特性你了解吗

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

C++ 函数继承详解:如何处理继承中出现的二义性?

解决继承中的二义性存在同名函数时,可以通过以下方法解决二义性:使用作用域解析符(::)指定函数所属的类。在派生类中重写基类函数。创建基类指针并指向派生类对象,然后使用指针调用基类函数。C++ 函数继承详解:处理继承中的二义性继承中的二义性
C++ 函数继承详解:如何处理继承中出现的二义性?
2024-04-30

web前端入门到实战:你真的了解CSS继承吗?看完必跪

也许你瞧不起以前的 css ,但是你不该再轻视眼下的 css 。近年来 css 的变量系统已逐步得到各大浏览器厂商支持,自定义选择器等强势袭来,嵌套系统/模块系统也在路上...为了更好的掌握 css 这门语言,很有必要把之前零零散散的 cs
2023-06-03

C语言中的柔性数组你了解吗

这篇文章主要为大家详细介绍了C99中的新语法——柔性数组的使用以及优缺点,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的可以了解一下
2023-05-15

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录