c++父类,子类,成员变量的构造/析构顺序,以及创建对象时一些小细节

父类,子类,成员变量的构造/析构顺序:

  1. 先调用基类的构造函数
  2. 再调用子对象类(成员变量)的构造函数
  3. 最后调用派生类的构造函数
  4. 调用顺序与派生类构造函数冒号后面给出的初始化列表(Derived(): m1(), m2(), Base1(), Base2())没有任何关系,按照继承的顺序和变量再类里面定义的顺序进行初始化。 先继承Base2,就先构造Base2。先定义m2,就先构造m2。
  5. 析构函数调用顺序仍然与构造函数构造顺序相反。(成员和对象的析构函数调用顺序是:先调用对象的析构函数,然后再在析构函数里调用成员的析构函数)

如果自定义了构造函数,则编译器就不会自动生成默认构造函数,但仍会生成默认拷贝构造函数;

如果自定义了拷贝构造函数,则编译器就不会自动生成默认移动构造函数;

如果没有显示声明定义析构函数,则编译器会自动生成非虚版本的析构函数。

 

1. 父类型指针 a = new 子类型; delete a时,父/子类的构造/析构函数时如何调用的?

直接看下面例子:

 1 #include <memory>
 2 #include <iostream>
 3 
 4 using namespace std;
 5 
 6 class BF{
 7     public:
 8         BF(){ cout << "base::base()\n";fun();}
 9         virtual ~BF(){cout << "~base::base()\n";fun();}
10         virtual void fun(){cout << "base::fun() virtual\n";}
11 };
12 
13 class derive: public BF
14 {
15
17 public:
18     derive(){cout << "derive::derive()\n";fun();}
19     ~derive(){cout << "~derive::derive()\n";fun();}
20     virtual void fun(){cout << "derive::fun() virtual\n";}
21 };
22 
23 int main()
24 {
25     cout << "-------------------" << endl;
26     BF *b = new BF();
27     delete b;
28     cout << "-------------------" << endl;
29     derive *d = new derive();
30     delete d;
31     cout << "-------------------" << endl;
32     BF *bd = new derive();
33     delete bd;
34     return 0;
35     
36 }

运行结果:

-------------------
base::base()
base::fun() virtual
~base::base()
base::fun() virtual
-------------------
base::base()
base::fun() virtual
derive::derive()
derive::fun() virtual
~derive::derive()
derive::fun() virtual
~base::base()
base::fun() virtual
-------------------
base::base()
base::fun() virtual
derive::derive()
derive::fun() virtual
~derive::derive()
derive::fun() virtual
~base::base()
base::fun() virtual

 

结论: 类型A指针 a = new 类型B 时,无论类型A如何,都是调用类型B的构造函数来初始化,delete a时也是调用类型B的析构函数

 

2. C++创建类对象时(无参)后不加括号与加括号的区别(参考:https://www.cnblogs.com/traeyee/p/4892410.html)

直接看例子:

 1 #include<iostream>
 2 using namespace std;
 3 
 4 class C{
 5 public:
 6     C(){
 7         cout<<"Hello C++\n";
 8     };
 9     C(int m){
10         cout<<"I love C++\n";
11     };
12 private:
13     int n;
14 };
15 
16 int main(){
17     cout << "-------get parameter------" << endl;
18     C a(1);
19     cout << "-------get ()------" << endl;
20     C b();
21     cout << "-------nothing------" << endl;
22     C c;
23     return 0;
24 }

运行结果:

-------get parameter------
I love C++
-------get ()------
-------nothing------
Hello C++

 

结论:

给参数时,调用相应的构造函数,在栈内存中实例化对象;

只有一个括号时……这尼玛是声明了一个返回该类对象的函数

啥都没有只有对象名时,调用默认构造函数(如果没有定义默认构造函数则出错)。

 

3. C++中 new 一个对象 时加括号和不加括号的区别

 1 #include<iostream>
 2 using namespace std;
 3 
 4 class C{
 5 public:
 6     C(){
 7         cout<<"Hello C++\n";
 8     };
 9     C(int m){
10         cout<<"I love C++\n";
11     };
12 private:
13     int n;
14 };
15 
16 int main(){
17     cout << "-------get parameter------" << endl;
18     C* a = new C(1);
19     cout << "-------get ()------" << endl;
20     C* b = new C();
21     cout << "-------nothing------" << endl;
22     C* c = new C;
23     return 0;
24 }

运行结果:

-------get parameter------
I love C++
-------get ()------
Hello C++
-------nothing------
Hello C++

 

结论:

传入参数时,会调用相应的构造函数;没有参数时,无论是否加括号,都会调用默认构造函数

 

posted @ 2021-01-30 11:09  大黑耗  阅读(521)  评论(0编辑  收藏  举报