C/C++ 多继承{虚基类,虚继承,构造顺序,析构顺序}
C/C++:一个基类继承和多个基类继承的区别
1.对多个基类继承会出现类之间嵌套时出现的同名问题,如果同名变量或者函数出现不在同一层次,则底层派生隐藏外层比如继承基类的同名变量和函数,不会出现二义性,而如果出现在同一阶层, 则会 出现二义性,解决办法:要么在同一阶层的底层(派生类)中重新定义可以解决,或者使用虚基类(减少部分二义性)
2.虚基类:在派生列表中使用virtual关键字的基类(即使这部分虚基类在继承中多次出现,但只初始化一份) 虚继承:虚基类将被 "最底层派生类"(任何虚基类以下派生类都可能是最底层派生类,所以都应该提供虚基类的初始值(即构造虚基类))初始化,因此最底层派生类应该含有它所有虚基类的初始值(即构造虚基类)
3.虚基类保证多次继承相同基类但只有一份基类数据(保证共享);
4.虚继承的构造顺序由编译器按照派生类列表从左往右寻找直接继承的虚基类/间接继承的虚基类,先构造虚基类部分,然后按照正常构造从左到右构造,最后构造本身,而析构相反
5.派生类的合成拷贝和构造,赋值都是按照上述规则执行,所以手动写拷贝,构造,和赋值时,需要按照这个顺序构造
6.所以虚继承出现在虚基类之后(个人理解)
C/C++代码:
#include <cstdlib>
#include <iostream> class Class
{
}; class Base : public Class
{
protected:
int value;
public:
Base() : value()
{}; Base(const Base &rhs) : Class(), value(rhs.value)
{}; Base(int a) : value(a), Class()
{};
}; class D1 : virtual public Base
{
public:
D1() : Base()
{}; D1(int a) : Base(a)
{}; D1(const D1 &rhs) : Base(rhs)
{};
}; class D2 : virtual public Base
{
public:
D2() : Base()
{}; D2(int a) : Base(a)
{}; D2(const D2 &rhs) : Base(rhs)
{};
}; class MI : public D1, public D2
{
public:
MI() : D1(), D2()
{} MI(int a) : Base(a), D1(a), D2(a)
{}; MI(const MI &rhs) : Base(rhs), D1(rhs), D2(rhs)
{};
}; class Final : public MI, public Class
{
public:
using Base::value; //using 可改变继承变量权限 Final()
{}; Final(int a) : Base(a), MI(a), Class() //可通过不写Base(a),输出value查看,value是否被赋值
{}; Final(const Final &rhs) : Base(rhs), MI(rhs), Class()
{}; }; int main()
{
Final A();
std::cout << A.value << std::endl;
return ;
}
C/C++ 多继承{虚基类,虚继承,构造顺序,析构顺序}的更多相关文章
- C++ 由虚基类 虚继承 虚函数 到 虚函数表
//虚基类:一个类可以在一个类族中既被用作虚基类,也被用作非虚基类. class Base1{ public: Base1(){cout<<"Construct Base1!&q ...
- 虚基类&虚继承
发现这个月准备竞赛完全没有更新哎... 改了下某华大一c++测试题...网上对虚继承讲的要么太繁琐要么不到位,自力更生 #include<iostream> #include<fst ...
- 3.10 C++虚基类 虚继承
参考:http://www.weixueyuan.net/view/6367.html 总结: 本例即为典型的菱形继承结构,类A中的成员变量及成员函数继承到类D中均会产生两份,这样的命名冲突非常的棘手 ...
- C++ 类成员的构造和析构顺序
我想对面向对象有了解的童鞋应该不会对类和对象感到陌生吧 ! 对象并不是突然建立起来的,创建对象必须时必须同时创建父类以及包含于其中的对象.C++遵循如下的创建顺序: (1)如果某个类具体基类,执行基类 ...
- C++ 多继承与虚基类
转载来自:CSDN insistGoGo (http://blog.csdn.net/insistgogo) 多继承的定义:派生类的基类大于一个 语法: class 派生类名:继承方式1 基类名1 ...
- C++ 虚基类 派生与继承
在学习设计模式时我就有一个疑问,关联和继承除了用法上的区别,好像在内存上并没有什么区别,继承也是父类作为了子类的元素(内存上),关联也是这样.而且关联好像更占内存一些.这就是设计模式里问题了“依赖倒转 ...
- 从汇编看c++中含有虚基类对象的析构
c++中,当继承结构中含有虚基类时,在构造对象时编译器会通过将一个标志位置1(表示调用虚基类构造函数),或者置0(表示不调用虚基类构造函数)来防止重复构造虚基类子对象.如下图菱形结构所示: 当构造类B ...
- RTTI、虚函数和虚基类的实现方式、开销分析及使用指导(虚函数的开销很小,就2次操作而已)
白杨 http://baiy.cn “在正确的场合使用恰当的特性” 对称职的C++程序员来说是一个基本标准.想要做到这点,首先要了解语言中每个特性的实现方式及其开销.本文主要讨论相对于传统 C 而言, ...
- 【C++】继承(虚基类)
类的继承与派生 面向对象技术强调软件的可重用性,这种重用性通过继承机制来实现.而在类的继承过程中,被重用的原有类称为基类,新创建的类称为派生类.派生类定义语法格式如下: class <派生类名& ...
随机推荐
- xlutils模块使用
python常用模块目录 1.xlutils 实现拷贝原文件 原表格: import xlrd from xlutils.copy import copy workbook = xlrd.open_w ...
- AJAX(Asynchronous JavaScript and XML)学习笔记
基本概念: 1.AJAX不是一种新的编程语言,而是一种使用现有标准的新方法. 2.AJAX最大的优点是在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页内容,用于创建快速动态网页(传统网页如 ...
- Daily Scrum (2015/10/29)
今天晚上我们学霸项目的三个小组在一起开会,讨论如何能在后期使我们三个项目更好地结合在一起.为了三个小组的能够同时工作,不出现某一小组因需要其他小组成果而停滞的情况,我们决定围绕lucene,solr, ...
- 20172319 实验二《Java面向对象程序设计》实验报告
20172319 2018.04.17-30 实验二<Java面向对象程序设计>实验报告 课程名称:<程序设计与数据结构> 学生班级:1723班 学生姓名:唐才铭 学生学号:2 ...
- DPDK实例程序:testpmd
用户手册:https://doc.dpdk.org/guides/testpmd_app_ug/index.html 还不错的入门:http://syswift.com/188.html 我的运行情况 ...
- week4b:个人博客作业
下面是week4做程序的过程. 1.在做之前先做客户需求,要求使用的使用mul图. 自己第一次听到这个名字,网上查UML为, http://www.cnblogs.com/wangkangluo1/a ...
- ReentrantLock 和 Condition的使用
ReentrantLock ReentrantLock可以等同于synchronized使用. ReentrantLock 类实现了Lock ,它拥有与 synchronized 相同的并发性和内存 ...
- Linux操作系统(二)
SSD工作原理:http://www.360doc.com/content/15/0318/15/16824943_456186965.shtml HHD工作原理:http://blog.csdn.n ...
- java 表单验证
java 表单验证 1.思路:通过表单选择器,表单属性过滤器提取每个表单提交的值,进行验证 2.实现:javascript通过 onSubmit()事件,判断,返回值false不提交,返回true提交 ...
- PostgreSQL窗口函数
窗口函数允许在查询的SELECT列表和ORDER BY子句中使用. 如果有排序,要保证唯一,否则会有下面的错误: 修改方式是:保证唯一,修改方法如下: