C++继承中构造与析构、父子间的冲突有哪些(C++,编程语言)

时间:2024-05-04 10:34:07 作者 : 石家庄SEO 分类 : 编程语言
  • TAG :

一.继承中的构造与析构

Q:如何初始化父类成员?父类构造函数与子类构造函数由什么关系?
A.子类对象的构造
1.子类在可以定义构造函数
2.子类构造函数--必须对继承而来的成员进程初始化(直接通过初始化列表或者赋值的方式进行初始化,调用父类构造函数进行初始化)
B.父类构造函数在子类中的调用方式
1.默认调用--适用于无参构造函数和使用默认参数的构造函数
2.显示调用--通过初始化列表进行调用,适用于所有父类构造函数
代码示例

#include<iostream>#include<string>usingnamespacestd;classParent{public:Parent(){cout<<"Parent()"<<endl;}Parent(strings){cout<<"Parent(strings):"<<s<<endl;}};classChild:publicParent{public:Child()//对父类构造函数进行隐式调用{cout<<"Child()"<<endl;}Child(strings):Parent(s)//对父类构造函数进行显示调用{cout<<"Child(strings):"<<s<<endl;}};intmain(){Childc;Childcc("cc");return0;}

运行结果如图所示
C++继承中构造与析构、父子间的冲突有哪些
由该示例和运行结果可以对构造规则进行一个总结:子类对象在创建时首先会调用父类的构造函数,先执行父类构造函数在执行子类的构造函数,父类构造函数可以被隐式调用或者显示调用
子类对象的构造:1.调用父类的构造函数2.调用成员变量的构造函数3.调用类自身的构造函数
子类构造深度解析

#include<iostream>#include<string>usingnamespacestd;classObject{public:Object(strings){cout<<"Object(strings):"<<s<<endl;}};classParent:publicObject{public:Parent():Object("Default"){cout<<"Parent()"<<endl;}Parent(strings):Object(s){cout<<"Parent(strings):"<<s<<endl;}};classChild:publicParent{ObjectmO1;ObjectmO2;public:Child():mO1("Default1"),mO2("Default2"){cout<<"Child()"<<endl;}Child(strings):Parent(s),mO1(s+"1"),mO2(s+"2"){cout<<"Child(strings):"<<s<<endl;}};intmain(){Childcc("cc");return0;}

运行结果
C++继承中构造与析构、父子间的冲突有哪些
Object mO1 Object mO2是组合关系,要对父类进行显式的调用,该打印结果与上面所提的构造顺序是相符的
C.子类对象的析构
析构函数的调用顺序与构造函数相反
1.执行自身的析构函数
2.执行成员变量的析构函数
3.执行父类的析构函数

代码示例

#include<iostream>#include<string>usingnamespacestd;classObject{stringms;public:Object(strings){cout<<"Object(strings):"<<s<<endl;ms=s;}~Object(){cout<<"~Object():"<<ms<<endl;}};classParent:publicObject{stringms;public:Parent():Object("Default"){cout<<"Parent()"<<endl;ms="Default";}Parent(strings):Object(s){cout<<"Parent(strings):"<<s<<endl;ms=s;}~Parent(){cout<<"~Parent():"<<ms<<endl;}};classChild:publicParent{ObjectmO1;ObjectmO2;stringms;public:Child():mO1("Default1"),mO2("Default2"){cout<<"Child()"<<endl;ms="Default";}Child(strings):Parent(s),mO1(s+"1"),mO2(s+"2"){cout<<"Child(strings):"<<s<<endl;ms=s;}~Child(){cout<<"~Child()"<<ms<<endl;}};intmain(){Childcc("cc");cout<<endl;return0;}

运行结果
C++继承中构造与析构、父子间的冲突有哪些
小结:
1.子类对象在创建时需要调用父类构造函数进行初始化
2.先执行父类构造函数然后执行成员的构造函数
3.父类构造函数显示调用需要在初始化列表中进行
4.子类对象在销毁时需要调用父类析构函数进行清理
5.析构函数与构造函数对称相反

二.父子间的冲突

Q:子类中是否可以定义父类的同名成员?如果可以?怎样区分?如果不行,为什么?
代码示例

#include<iostream>#include<string>usingnamespacestd;classParent{public:intmi;};classChild:publicParent{public:intmi;};intmain(){Childc;c.mi=100;//mi究竟是子类自定义的,还是从父类继承得到的?cout<<"c.mi="<<c.mi<<endl;return0;}

运行结果
C++继承中构造与析构、父子间的冲突有哪些
从该示例以及运行结果我们会得出一些疑问,根据继承的概念,子类拥有父类的所有属性和行为,在该程序中父类与子类都定义了mi,而在其初始化时,不确定是子类自定义的,还是从父类继承得到的。造成了父子间的冲突。
A.父子间的冲突
1.子类可以定义父类中的同名成员
2.子类中的成员将隐藏父类中的同名成员
3.父类的中的同名成员依然存在于子类中
4.通过作用域分辨符(::)访问父类的同名成员
C++继承中构造与析构、父子间的冲突有哪些
同名成员变量深度分析--代码示例

#include<iostream>#include<string>usingnamespacestd;namespaceA{intg_i=0;}namespaceB{intg_i=1;}classParent{public:intmi;Parent(){cout<<"Parent():"<<"&mi="<<&mi<<endl;}};classChild:publicParent{public:intmi;Child(){cout<<"Child():"<<"&mi="<<&mi<<endl;}};intmain(){Childc;c.mi=100;c.Parent::mi=1000;cout<<"&c.mi="<<&c.mi<<endl;cout<<"c.mi="<<c.mi<<endl;cout<<"&c.Parent::mi="<<&c.Parent::mi<<endl;cout<<"c.Parent::mi="<<c.Parent::mi<<endl;return0;}

运行结果
C++继承中构造与析构、父子间的冲突有哪些
可以从该段代码的运行结果看出,通过地址值可以很清楚得看出,父类与子类到底调用的是哪个
B:再论重载
类中的成员函数可以进行重载
1.重载函数的本质为多个不同的函数
2.函数名域参数列表是唯一的标识
3.函数重载必须发生在同一作用域中

父子间函数重载实验
代码示例及运行结果

#include<iostream>#include<string>usingnamespacestd;classParent{public:intmi;voidadd(intv){mi+=v;}voidadd(inta,intb){mi+=(a+b);}};classChild:publicParent{public:intmi;voidadd(intv){mi+=v;}voidadd(inta,intb){mi+=(a+b);}voidadd(intx,inty,intz){mi+=(x+y+z);}};intmain(){Childc;c.mi=100;c.Parent::mi=1000;cout<<"c.mi="<<c.mi<<endl;cout<<"c.Parent::mi="<<c.Parent::mi<<endl;c.add(1);c.add(2,3);c.add(4,5,6);cout<<"c.mi="<<c.mi<<endl;cout<<"c.Parent::mi="<<c.Parent::mi<<endl;return0;}

C++继承中构造与析构、父子间的冲突有哪些
父子间的冲突
1.子类中的函数将隐藏父类的同名函数
2.子类无法重载父类中的成员函数
3.使用作用域分辨符访问父类中的同名函数
4.子类可以定义父类中完全相同的成员函数

 </div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
本文:C++继承中构造与析构、父子间的冲突有哪些的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:c语言实现不同输出下一篇:

7 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18