C++继承与派生(原理归纳)
1. C++继承与java不同,java遵循单继承,但java的接口为其不足做了很好的弥补了。 C++则是灵活的多,为多继承。即一个C++类可以同时继承N个类的属性。
2. 对于继承方式 :
有三种: public ,private,protect,对于public继承的类,其公有成员依然是公有成员,私有成员依旧是私有成员。
对于protect,private 则有限制 ,就好比一个水管,公有水管是最大号的,对于水的流量没有限制。保护水管,是中等的号的,对于大号水管的流量使其变成中等流量,对于中等以下的不限制。私有水管,则是最小号的,对于大于私有水管限制的统统的改为私有水管的标准。 其中私有继承,其实就是一种绝育的措施。就是以后的继承就没有太大意义。
3.对于继承关于构造和析构顺序原里的归纳:
看代码:
1 #include<iostream>
2 using namespace std ;
3
4 class Base1 {
5
6 public :
7 Base1() {
8 cout << "Default Base1" << endl;
9 }
10 Base1(int i) {
11 cout << "Base1"<<i<< endl;
12 }
13 ~Base1() {
14 cout << "Base1 析构" << endl;
15 }
16 };
17
18 class Base2 {
19
20 public :
21 Base2() {
22 cout << "Default Base2" << endl;
23 }
24 ~Base2() {
25 cout << "Base2 析构" << endl;
26 }
27 Base2(int i) {
28 cout << "Base2" << i << endl;
29 }
30 };
31 class Base3 {
32
33 public :
34 Base3() {
35 cout << "Default Base3" << endl;
36 }
37 ~Base3() {
38 cout << "Base3 析构" << endl;
39 }
40 Base3(int i) {
41 cout << "Base3" << i << endl;
42 }
43
44 };
45
46
47 class Derived : public Base1, public Base2, public Base3 //(1)先 在这儿开始构造从左到右
48 //析构则是从右到左
49 {
50
51 public :
52 Derived() {
53 cout << "Default Derived" << endl;
54 }
55 ~Derived() {
56 cout << "Derived 析构" << endl;
57 }
58 Derived( int a , int b , int c , int d )
59 :men2(b),Base1(a),Base3(c), Base2(d),men1(b) {
60 cout << "Derived" << endl;
61 };
62
63 private :
64 //构造从左到右
65 Base3 men3;
66 Base2 men2;
67 Base1 men1;
68
69 //析构则是从底部开始往上析构,先 Base 1,2,3
70 };
71
72 int main(void ) {
73
74 Derived obj(1,2,3,4);
75 return 0;
76
77 }
4. 以上是对于单继承的描述,如果是多继承,那么常规的话,我们很容易清楚器执行顺序,但是如果是虚继承,其执行顺序又会如何 ?
1. 现在我们来看这样一个图:它的运行结果又是如何.......
1 #include<iostream>
2 using namespace std;
3
4 class Boss {
5
6 public :
7 Boss() {
8 cout << "this is Boss's constructor !" << endl;
9 };
10 Boss(int i) {
11 cout << "this is Boss's constructor !"
12 << " moneny=" << i << endl;
13 }
14
15 void show() {
16 cout<<"宝剑磨砺,斩魂妖,时光磨砂,魔刃出"<<endl;
17 }
18 virtual ~ Boss() {
19 cout << "this is Boss's xigou function !" << endl;
20 }; //虚析构函数
21 };
22
23 //店小二
24 class xiao_er :virtual public Boss
25 {
26 public:
27 xiao_er() {
28 cout << "this is xiao_er's constructor !"<<endl;
29 }
30 xiao_er(int i) : Boss(i){
31 cout << "this is xiao_er's constructor !"
32 << " moneny=" << i << endl;
33 }
34 virtual ~xiao_er() {
35 cout << "this is xiao_er's xigou function !" << endl;
36 }
37 void show() {
38 cout << "我是店小二,客官 !" << endl;
39 }
40 };
41
42 //王二小
43 class er_xiao : virtual public Boss
44 , virtual public xiao_er /*其实这里这个可以省去,但是这儿是为了写代码而写代码*/
45 {
46 public :
47 er_xiao() {
48 cout << "this is er_xiao's constructor !" << endl;
49 }
50 er_xiao(int i) :
51 Boss(i) , xiao_er(i+1)
52 {
53 cout << "this is er_xiao's constructor !"
54 << " moneny=" << i << endl;
55 }
56 virtual ~ er_xiao() {
57 cout << "this is er_xiao's xigou function !"<<endl;
58 }
59 void show() {
60 cout << "我是王二小,为坏人带路的王二小 !" << endl;
61 }
62 };
63
64 //天朝VIP员工
65 class VIP_em : virtual public Boss
66 {
67
68 public:
69 VIP_em(){
70 cout << "this is VIP_em's constructor !" << endl;
71 }
72
73 VIP_em(int i) :
74 Boss(i)
75 {
76 cout << "this is VIP_em's constructor !"
77 << " moneny=" << i << endl;
78 }
79 virtual ~VIP_em() {
80 cout << "this is VIP_em's xigou function !" << endl;
81 }
82 void show() {
83 cout << "我是VIP , 我有特权! "<<endl;
84 }
85 };
86
87 //熊孩子
88 class stupid_kid : virtual public VIP_em
89 , virtual public xiao_er ,
90 virtual public er_xiao
91 {
92 public:
93 stupid_kid() {
94 cout << "this is stupid_kid's constructor !" << endl;
95 }
96
97 stupid_kid(int i) :
98 VIP_em(i) , xiao_er(12) , er_xiao(13),xe(i)
99 {
100 cout << "this is stupid_kid's constructor !"
101 <<" moneny="<<i<<endl;
102 }
103 ~stupid_kid() {
104 cout << "this is stupid_kid's xigou function !"<<endl;
105 }
106
107 void show() {
108 cout << "我是熊孩子,蜀黍,蜀黍,抱抱!" << endl;
109 }
110 private :
111 VIP_em vi;
112 xiao_er xe;
113 er_xiao ex;
114 };
115
116 int main(){
117
118 stupid_kid st(100);
119 //父类的函数被覆盖了
120 st.show();
121 //如何调用父类,强制是一种。
122 ((Boss)st).show();
123
124 //stupid_kid *pt = &st;
125 //stupid_kid &sb = st;
126 // pt->show();
127 //((Boss)sb).show();
128 return 0;
129 }
结果为:
this is Boss's constructor ! this is VIP_em's constructor ! moneny=100 this is xiao_er's constructor ! moneny=12 this is er_xiao's constructor ! moneny=13
-------------这部分为熊孩子的继承部分构造函数
下面是私有变量的构造函数
this is Boss's constructor ! this is VIP_em's constructor !
------私有变量 Vip_em调用无参数的构造函数 this is Boss's constructor ! moneny=100 this is xiao_er's constructor ! moneny=100
------私有变量 xiao_er调用有参数的构造函数
this is Boss's constructor ! this is xiao_er's constructor !
------私有变量 xiao_er调用无参数的构造函数 this is er_xiao's constructor !
this is stupid_kid's constructor ! moneny=100 我是熊孩子,蜀黍,蜀黍,抱抱! 宝剑磨砺,斩魂妖,时光磨砂,魔刃出 this is Boss's xigou function ! this is stupid_kid's xigou function ! this is er_xiao's xigou function ! this is xiao_er's xigou function ! this is Boss's xigou function ! this is xiao_er's xigou function ! this is Boss's xigou function ! this is VIP_em's xigou function ! this is Boss's xigou function ! this is er_xiao's xigou function ! this is xiao_er's xigou function ! this is VIP_em's xigou function ! this is Boss's xigou function ! 请按任意键继续. . .
6、 从上述代码可以不难看出, 虚内继承,避免了二义性,仅仅压缩了公有的你虚类继承类。
如果要弄清楚虚拟继承,就得先知道virtual table (vtbl) ----我们说的虚函数表
在内存那块, 会留 下一块连续的内存块,用作vtble存储JMP地址,而vtble里头存的便是virtual function(虚函数)地址,
每次继承时,基类都会产生一个vptr指针,指向派生类的地质,当 vptr指针指着同一个地址时,就不重复构造。 其他的,构造函数和析构函数,基于第一个代码列子。 根据自己对源码的理解和测试的总结,如有错误,还请多多指正。
- 调用finecms栏目多图怎么实现
- phpcms调用子栏目名称/文章怎么操作
- 小程序开发工具全新上线 附下载地址和教程
- JS页面跳转代码怎么写?总结了5种方法
- finecms如何控制调用子栏目的数量
- finecms如何调用多个指定栏目的内容
- finecms同时调用子栏目和子栏目的文章怎么操作
- 群体智能算法-黏菌寻找食物最优路线行为模拟 2
- thinkcmf安装教程与目录结构详解 快速上手版
- finecms如何批量替换文章中的关键词?
- dedecms批量修改文章为待审核稿件怎么操作
- 群体智能算法-黏菌寻找食物最优路线行为模拟
- finecms设置伪静态后分享到微信不能访问怎么处理
- composer安装其实可以很简单 两行命令就解决了
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 三千字带你搞懂XXL-JOB任务调度平台
- Python-科学计算-pandas-14-df按行按列进行转换
- Python实现扫码工具
- C++核心准则T.150:用static_assert检查类和概念的匹配性
- 初学者也能快速写Python脚本啦——通用功能代码分享
- C++核心准则CPL.1:C++比C更好
- C++核心准则CPL.2:如果你必须使用C,使用C和C++的共同子集,并且使用C++编译器编译C代码
- C++核心准则SF.1:如果你的项目没有正在遵从的其他习惯,为代码文件使用.cpp后缀,为接口文件使用.h后缀
- 群晖NAS搭建测速网站,支持万兆
- 二叉树:你真的会翻转二叉树么?
- C++核心准则SF.2:.h文件一定不能包含对象定义或者非inline函数定义
- Vue.js 源码⽬录设计
- 本周小结!(二叉树)
- extern "c"(2)
- Mysql 触发器基础