-
思考问题:如何初始化父类成员?父类构造函数和子类构造函数有什么关系呢?
-
子类对象的构造
-
子类中可方式以定义构造函数
-
子类构造函数必须对继承而来的成员进行初始化:
1)直接通过初始化列表或者赋值的方式进行初始化
2)调用父类构造函数进行初始化
-
父类构造函数在子类中的调用方式
-
默认调用:适用于无参构造函数和使用默认参数的构造函数
-
显示调用:通过初始化列表进行调用,适用于所有父类构造函数
-
如果子类没有显示调用,那么在父类中需要有无参构造函数
class Child : public Parent { public: //隐式调用父类中的无参构造函数 Child() { cout << "Child()" << endl; } //显式调用父类构造函数 Child(string _str) : Parent(_str) { name = _str; cout << "Child(string _str):"<< name<< endl; } };
-
构造规则
-
子类对象在创建时会首先调用父类的构造函数
-
先执行父类构造函数再执行子类的构造函数
-
父类构造函数可以被隐式调用或者显式调用
-
对象创建时构造函数的调用顺序
-
调用父类的构造函数
-
调用成员变量的构造函数
-
调用类自身的构造函数
-
口诀:先父母,后客人,再自己。
-
实验
// 继承的构造和析构.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include <iostream> #include <string> using namespace std; class Grandfather { public: Grandfather() { cout << " Grandfather()" << endl; } Grandfather(string _str) { cout << "Grandfather(string _str):" << _str << endl; } }; class Parent :public Grandfather { protected: string name; public: Parent() : Grandfather("default") { cout << "Parent()" << endl; } Parent(string _str):Grandfather("Grandfather") { name = _str; cout << "Parent(string _str):"<<name << endl; } }; class Child : public Parent { Grandfather guest; public: Child() : guest("default") { cout << "Child()" << endl; } //显式调用父类构造函数 Child(string _str) : Parent("father"),guest("guest") { name = _str; cout << "Child(string _str):"<< name<< endl; } }; int main() { Child chenge("son"); }
-
运行结果
Grandfather(string _str):Grandfather
Parent(string _str):father
Grandfather(string _str):guest
Child(string _str):son
-
子类对象的析构
-
执行自身的析构函数
-
执行成员变量的析构函数
-
执行父类的析构函数
-
实验:
1 // 继承的构造和析构.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 2 // 3 #include <iostream> 4 #include <string> 5 using namespace std; 6 class Grandfather 7 { 8 string name; 9 public: 10 Grandfather() 11 { 12 cout << " Grandfather()" << endl; 13 } 14 Grandfather(string _str) 15 { 16 name = _str; 17 cout << "Grandfather(string _str):" << _str << endl; 18 } 19 ~Grandfather() 20 { 21 cout << "~Grandfather():" << name << endl; 22 } 23 }; 24 class Parent :public Grandfather 25 { 26 string name; 27 public: 28 Parent() : Grandfather("default") 29 { 30 name = "default"; 31 cout << "Parent()" << endl; 32 } 33 Parent(string _str):Grandfather("Grandfather") 34 { 35 name = _str; 36 cout << "Parent(string _str):"<<name << endl; 37 } 38 ~Parent() 39 { 40 cout << "~Parent():" << name << endl; 41 } 42 }; 43 class Child : public Parent 44 { 45 string name; 46 Grandfather guest; 47 public: 48 Child() : guest("default") 49 { 50 name = "default"; 51 cout << "Child()" << endl; 52 } 53 //显式调用父类构造函数 54 Child(string _str) : Parent("father"),guest("guest") 55 { 56 name = _str; 57 cout << "Child(string _str):"<< name<< endl; 58 } 59 ~Child() 60 { 61 cout << "~Child():" << name << endl; 62 } 63 }; 64 int main() 65 { 66 Child chenge("son"); 67 }
-
运行结果
Grandfather(string _str):Grandfather
Parent(string _str):father
Grandfather(string _str):guest
Child(string _str):son
~Child():son
~Grandfather():guest
~Parent():father
~Grandfather():Grandfather
-
小结
-
子类对象在创建时需要调用父类构造函数进行初始化
-
先执行父类构造函数然后执行成员的构造函数
-
父类构造函数显式调用需要在初始化列表中进行
-
子类对象在销毁时需要调用父类析构函数进行清理
-
析构顺序与构造顺序对称相反