C++继承中的构造和析构

1,构造:对象在创建的后所要做的一系列初始化的工作;

析构:对象在摧毁之前所要做的一系列清理工作;

2,思考:

1,子类中如何初始化父类成员?

1,对于继承而言,子类可以获得父类的代码,可以获得父类中的成员变量,成员变量从父类中传递到子类,那么子类对象在创建的时候如何初始化从父类中继承的成员变量呢?

2,父类构造函数和子类构造函数有有什么关系?

3,子类对象的构造:

1,子类中可以定义构造函数;

  1,子类中定义的新的构造函数,对于子类对象创建的时候必须完成一系列的初始化工作,这些初始化工作包括初始化继承而来的成员,第一种方式直接对他们进行赋值或者直接将他们写到初始化列表中去进行初始化,第二种方式更直接,在子类构造的时候我们调用父类构造函数进行初始化;

  2,这就是子类构造函数可以用来初始化父类成员的两种方式;

2,子类构造函数:

  1,必须对继承而来的成员进行初始化;

  1,直接通过初始化列表或者赋值的方式进行初始化;

    1,有可能从父类中继承了 private 成员,因此直接来进行赋值或初始化根本就是行不通的,因此这个时候只能通过父类的构造函数来进行初始化的工作;

  2,调用父类构造函数进行初始化;

3,父类构造函数在子类中的调用方式;

  1,默认调用:

  1,子类对象在创建的时候会自动的调用父类的构造函数;

  2,适用于无参构造函数和使用默认参数的构造函数;

    1,对于需要参数的构造函数来说,默认的调用方式是行不通的,必须显示调用;

  2,显示调用:

  1,通过初始化列表进行调用;

    1,只能在初始化列表中调用;

  2,适用于所有父类构造函数;

3,父类构造函数的调用:

1,代码示例:

 1 class Child : public Parent
 2 {
 3 Public:
 4     Child() /* 隐式调用 */
 5     {
 6          Cout << “Child()” << endl;
 7     }
 8
 9     Child(string s)  : Parent(“Parameter to Parent”)  /* 显示调用 */
10     {
11          Cout << “Child() : “ << s << endl;
12     }
13 };

4,子类的构造初探编程实验:

 1 #include <iostream>
 2 #include <string>
 3
 4 using namespace std;
 5
 6 class Parent
 7 {
 8 public:
 9     Parent()
10     {
11         cout << "Parent()" << endl;
12     }
13
14     Parent(string s)
15     {
16         cout << "Parent(string s) : " << s << endl;
17     }
18 };
19
20 class Child : public Parent
21 {
22 public:
23     Child()  // 隐式调用父类构造函数中的无参或默认初始值构造函数
24     {
25         cout << "Child()" << endl;
26     }
27
28     Child(string s)  // 隐式调用父类构造函数中的无参或默认初始值构造函数;
29     {
30         cout << "Child(string s) : " << s << endl;
31     }
32
33     Child(string s): Parent(s)  // 显示调用父类构造函数;
34     {
35         cout << "Child(string s) : " << s << endl;
36     }
37 };
38
39 int main()
40 {
41     Child c;  // 调用父类无参构造函数,然后调用子类无参构造函数;
42     Child cc("cc");  // 调用父类有参构造函数,然后调用子类构造函数;
43
44     return 0;
45 }

1,子类和父类的构造函数的调用都严格按照重载规则调用;

5,子类对象的构造:

1,构造规则:

1,子类对象在创建时会首先调用父类的构造函数(要以子类构造函数调用为依据);

2,先执行父类构造函数再执行子类构造函数;

3,父类构造函数可以被隐式调用或者显示调用;

2,对象创建时构造函数的调用顺序:

1,调用父类的构造函数;

2,调用成员变量的构造函数;

3,调用类自身的构造函数;

4,口诀:

1,先父母(调到最上的父母为止),后客人(按照成员变量申明的顺序),再自己;

2,非常实用;

3,子类构造深度解析编程实验:

 1 #include <iostream>
 2 #include <string>
 3
 4 using namespace std;
 5
 6 class Object
 7 {
 8 public:
 9     Object(string s)
10     {
11         cout << "Object(string s) : " << s << endl;
12     }
13 };
14
15 class Parent : public Object
16 {
17 public:
18     Parent() : Object("Default")  // 必须显示调用
19     {
20         cout << "Parent()" << endl;
21     }
22
23     Parent(string s) : Object(s)  // 必须显示调用
24     {
25         cout << "Parent(string s) : " << s << endl;
26     }
27 };
28
29 class Child : public Parent
30 {
31     Object mO1;  // 组合关系,默认构造函数和有参数构造函数,这里必须显示调用
32     Object mO2;
33
34 public:
35     Child() : mO1("Default 1"), mO2("Default 2")
36     {
37         cout << "Child()" << endl;
38     }
39
40     Child(string s) : Parent(s), mO1(s + " 1"), mO2(s + " 2")  // 父母和成员客人的区别在于父母构造函数直接调用,客人构造函数通过对象调用;
41     {
42         cout << "Child(string s) : " << s << endl;
43     }
44 };
45
46 int main()
47 {
48     Child cc("cc");
49
50     // cc output:
51     // Object(string s) : cc  父母
52     // Parent(string s) : cc  父母
53     // Object(string s) : cc 1  客人
54     // Object(string s) : cc 2  客人
55     // Child(string s) :  cc  自己
56
57     return 0;
58 }

6,子类对象的析构:

1,析构函数的调用顺序与构造函数相反:

1,执行自身的析构函数;

2,执行成员变量的析构函数;

3,执行父类的析构函数;

2,对象的析构编程实验:

 1 #include <iostream>
 2 #include <string>
 3
 4 using namespace std;
 5
 6 class Object
 7 {
 8     string ms;  // 为了验证析构函数的输出,定义了这个成员变量来传递值,因为构造函数可以由外界传入值,但是析构函数没有参数,是不可以由完结传入值的;
 9
10 public:
11     Object(string s)
12     {
13         cout << "Object(string s) : " << s << endl;
14         ms = s;
15     }
16
17     ~Object()
18     {
19         cout << "~Object() : " << ms << endl;
20     }
21 };
22
23 class Parent : public Object
24 {
25     string ms;
26
27 public:
28     Parent() : Object("Default")
29     {
30         cout << "Parent()" << endl;
31         ms = "Default";
32     }
33
34     Parent(string s) : Object(s)
35     {
36         cout << "Parent(string s) : " << s << endl;
37         ms = s;
38     }
39
40     ~Parent()
41     {
42         cout << "~Parent() : " << ms << endl;
43     }
44 };
45
46 class Child : public Parent
47 {
48     Object mO1;
49     Object mO2;
50     string ms;
51
52 public:
53     Child() : mO1("Default 1"), mO2("Default 2")
54     {
55         cout << "Child()" << endl;
56         ms = "Default";
57     }
58
59     Child(string s) : Parent(s), mO1(s + " 1"), mO2(s + " 2")
60     {
61         cout << "Child(string s) : " << s << endl;
62         ms = s;
63     }
64
65     ~Child()
66     {
67         cout << "~Child() " << ms << endl;
68     }
69 };
70
71 int main()
72 {
73     Child cc("cc");
74
75     cout << endl;
76
77     return 0;
78 }

7,小结:

1,子类对象在创建时需要调用父类构造函数进行初始化;

2,先执行父类构造函数然后执行成员的析构函数;

3,父类构造函数显示调用需要在初始化列表中进行;

4,子类对象在销毁时需要调用父类析构函数进行清理;

5,析构顺序与构造顺序对称相反;

1,先自己,后客人,再父母;

原文地址:https://www.cnblogs.com/dishengAndziyu/p/10915052.html

时间: 2024-10-10 07:37:03

C++继承中的构造和析构的相关文章

C++ 类的继承三(继承中的构造与析构)

//继承中的构造与析构 #include<iostream> using namespace std; /* 继承中的构造析构调用原则 1.子类对象在创建时会首先调用父类的构造函数 2.父类构造函数执行结束后,执行子类的构造函数 3.当父类的构造函数有参数时,需要在子类的初始化列表中显示调用 4.析构函数调用的先后顺序与构造函数相反 继承与其他类做成员变量混搭的情况下,构造和析构嗲用原则 1.先构造父类,在构造成员变量,最后构造自己 2.先析构自己,再析构成员变量,最后析构父类 */ clas

C++--继承中的构造与析构、父子间的冲突

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

C++--第16课 - 继承中的构造与析构

第16课 - 继承中的构造与析构 1. 赋值兼容性原则 (1)      子类对象可以当作父类对象使用. (2)      子类对象可以直接赋值给父类对象. (3)      子类对象可以直接初始化父类对象. (4)      父类指针可以直接指向子类对象. (5)      父类引用可以直接引用子类对象. 子类就是特殊的父类 #include <cstdlib> #include <iostream> using namespace std; class Parent { pro

【C++第十课】---继承中的构造与析构

一.继承中的赋值兼容性原则 1.子类对象可以当作父类对象使用 2.子类对象可以直接赋值给父类对象 3.子类对象可以直接初始化父类对象 4.父类指针可以直接指向子类对象 5.父类引用可以直接引用子类对象 6.子类是就是特殊的父类. 举例说明: #include <iostream> using namespace std; class Parent { protected: const char* name; public: Parent() { name= "Parent ...&q

第46课 继承中的构造与析构

1. 子类对象的构造 (1)子类中可以定义构造函数 (2)子类构造函数,必须对继承而来的成员进行初始化,有两种方式 ①直接通过初始化列表进行初始化或赋值的方式进行初始化 ②调用父类构造函数进行初始化 (3)父类构造函数在子类中调用方式 ①默认调用:适用于无参构造函数和使用默认参数的构造函数 ②显式调用:通过初始化列表进行调用,适用于所有父类构造函数 [编程实验]子类的构造初探 #include <iostream> #include <string> using namespace

继承中的构造与析构(三十九)

我们思考下这个问题:如何初始化父类成员?父类构造函数和子类构造函数有何关系呢?在子类中可以定义构造函数,子类构造函数必须对继承而来的成员进行初始化:a> 直接通过初始化列表或者赋值的方式进行初始化:b> 调用父类构造函数进行初始化. 下来我们来说说父类构造函数在子类中的调用方式,分为两种:a> 默认调用:适用于无参构造函数和使用默认参数的构造函数:b> 显示调用:通过初始化列表进行调用,适用于所有父类构造函数.那么隐式调用是在子类的构造函数中啥都不加,显示调用时在子类构造函数后加上

第四十六课、继承中的构造与析构

一.子类对象的构造方法 1.子类中可以定义构造函数 2.子类构造函数:必须对继承来的成员进行初始化 (1).直接通过初始化列表或者赋值方式进行初始化(但可能继承来的是private成员) (2).调用父类构造函数进行初始化 A.默认调用:适用于无参构造函数和使用默认参数的构造函数 B.显示调用:通过初始化列表进行调用(适用于所有父类的构造函数) #include<iostream> #include<string> using namespace std; class Parent

Swift难点-继承中的构造规则实例具体解释

关于继承中的构造规则是一个难点. 假设有问题,请留言问我. 我的Swift新手教程专栏 http://blog.csdn.net/column/details/swfitexperience.html 为什么要有构造器:为类中自身和继承来的存储属性赋初值. 一.两种构造器-指定构造器和便利构造器 指定构造器:类中必备的构造器.为全部的属性赋初值.(有些子类可能不须要显示声明,由于默认从基类继承了) 便利构造器:类中的辅助构造器,通过调用指定构造器为属性赋初值.(仅在必要的时候声明) 举例 cla

Swift难点-继承中的构造规则实例详解

一.两种构造器-指定构造器和便利构造器 指定构造器:类中必备的构造器,为所有的属性赋初值.(有些子类可能不需要显示声明,因为默认从基类继承了) 便利构造器:类中的辅助构造器,通过调用指定构造器为属性赋初值.(仅在必要的时候声明) 举例 [plain] view plaincopy class Food { var name: String init(name: String) { self.name = name } convenience init() { self.init(name: "[