|
在我们前面学习过类中的构造函数,以及析构函数,那么自然而然,在继承关系中,必然是存在着析构和构造着。 一、子类对象的构造 1、问题的引出 如何初始化父类成员? 父类构造函数和子类构造函数有什么关系? 2、子类中的构造函数怎样初始化父类成员:
--必须对继承而来的成员进行初始化,那么怎样初始化呢?这里有两种方式: -直接通过初始化列表或者赋值的方式进行初始化 -调用父类构造函数进行初始化 3、父类构造函数在子类中的调用方式
-适用于无参构造函数和使用默认参数的构造函数
-通过初始化列表进行调用 -适用于所有父类构造函数 实践代码模板: class Child :public Parent{ public: Child()//隐式调用 { cout<< "Child()" <<endl; } Child(string s) :Parent("Parent to Parent") { cout<<"Child()"<<s<<endl; } }; 代码实践: #include <iostream>#include <string> using namespace std; class Parent { public: Parent() { cout << "Parent()" << endl; } Parent(string s) { cout << "Parent(string s) : " << s << endl; } }; class Child : public Parent { public: Child() { cout << "Child()" << endl; } Child(string s) : Parent(s) { cout << "Child(string s) : " << s << endl; } }; int main() { Child c; Child cc("cc"); return 0; } 输出结果: root@txp-virtual-machine:/home/txp# ./a.outParent() Child() Parent(string s) : cc Child(string s) : cc 注解:通过上面的代码输出结果,我们可以发现,子类定义的对象如果没有没有传参,就隐式调用父类的构造函数;当然上面也使用了显示调用,通过初始列表的就可以看出。 4、构造规则
5、对象创建时构造函数的调用顺序
总结:先父母,后客人,再自己 代码实践: #include <iostream>#include <string> using namespace std; class Object { public: Object(string s) { cout << "Object(string s) : " << s << endl; } }; class Parent : public Object { public: Parent() : Object("Default") { cout << "Parent()" << endl; } Parent(string s) : Object(s) { cout << "Parent(string s) : " << s << endl; } }; class Child : public Parent { Object mO1; Object mO2; public: Child() : mO1("Default 1"), mO2("Default 2") { cout << "Child()" << endl; } Child(string s) : Parent(s), mO1(s + " 1"), mO2(s + " 2") { cout << "Child(string s) : " << s << endl; } }; int main() { Child cc("cc"); return 0; } 输出结果: root@txp-virtual-machine:/home/txp# ./a.outObject(string s) : cc Parent(string s) : cc Object(string s) : cc 1 Object(string s) : cc 2 Child(string s) : cc 注解:我们可以看到,先定义了一个Child对象,然后最先访问Object带参构造函数,然后再是Parent带参构造函数(说白了就是父类先触发),然后在子类Child中又包含了组合关系(也就是客人),然后Object类中的带参构造函数,最后再触发自身的带参构造函数。 二、子类对象的析构 1、析构函数的调用顺序与构造函数相反
代码实践: #include <iostream>#include <string> using namespace std; class Object { string ms; public: Object(string s) { cout << "Object(string s) : " << s << endl; ms = s; } ~Object() { cout << "~Object() : " << ms << endl; } }; class Parent : public Object { string ms; public: Parent() : Object("Default") { cout << "Parent()" << endl; ms = "Default"; } Parent(string s) : Object(s) { cout << "Parent(string s) : " << s << endl; ms = s; } ~Parent() { cout << "~Parent() : " << ms << endl; } }; class Child : public Parent { Object mO1; Object mO2; string ms; public: Child() : mO1("Default 1"), mO2("Default 2") { cout << "Child()" << endl; ms = "Default"; } Child(string s) : Parent(s), mO1(s + " 1"), mO2(s + " 2") { cout << "Child(string s) : " << s << endl; ms = s; } ~Child() { cout << "~Child() " << ms << endl; } }; int main() { Child cc("cc"); cout << endl; return 0; } 输出结果: root@txp-virtual-machine:/home/txp# ./a.outObject(string s) : cc Parent(string s) : cc Object(string s) : cc 1 Object(string s) : cc 2 Child(string s) : cc ~Child() cc ~Object() : cc 2 ~Object() : cc 1 ~Parent() : cc ~Object() : cc 三、总结:
好了,今天的分享就到这里,如果文章中有错误或者不理解的地方,可以交流互动,一起进步。 |
微信公众号
手机版