C++中类的构造函数调用顺序

当建立一个对象时,首先调用基类的构造函数,然后调用下一个派生类的
构造函数,依次类推,直至到达派生类次数最多的派生次数最多的类的构造函数为止。
简而言之,对象是由“底层向上”开始构造的。因为,构造函数一开始构造时,总是
要调用它的基类的构造函数,然后才开始执行其构造函数体,调用直接基类构造函数时,
如果无专门说明,就调用直接基类的默认构造函数。在对象析构时,其顺序正好相反。

下面的这个程序说明这个问题

总结下来,我们必须明确的是当一个类继承与基类,并且自身还包含有其他类的成员对象的时候,构造函数的调用顺序为:调用基类的构造函数->调用成员对象的构造函数->调用自身的构造函数。构造函数的调用次序完全不受构造函数初始化列表的表达式中的次序影响,与基类的声明次数和成员对象在函数中的声明次序有关。

  1. C++子类和父类的构造函数调用顺序

[cpp] view plaincopy

  1. #include <iostream>
  2. using namespace std;
  3. //子类
  4. class base
  5. {
  6. public:
  7. base()
  8. {
  9. cout<<"i am base constuction!"<<endl;
  10. }
  11. };
  12. //父类
  13. class drived : public base
  14. {
  15. public:
  16. drived()
  17. {
  18. cout<<"i am drived constuction!"<<endl;
  19. }
  20. };
  21. int main()
  22. {
  23. drived d;
  24. //输出结果
  25. /*
  26. i am base constuction!
  27. i am drived constuction!
  28. Press any key to continue
  29. */
  30. return 0;
  31. }

由输出结果我们可以看到,先调用的是base类的构造函数,再调用了drived类的构造函数,也就是说,在声明子类实例的时候,是会先调用父类的构造函数的。这个很好理解,子类是包含了父类的信息的,所以要构造子类,必须先构造父类的信息,然后加入一些子类的新信息。

成员类的构造函数调用顺序

[cpp] view plaincopy

  1. #include <iostream>
  2. using namespace std;
  3. class son
  4. {
  5. public:
  6. son()
  7. {
  8. cout<<"i am son constuction!"<<endl;
  9. }
  10. };
  11. class family
  12. {
  13. public:
  14. family()
  15. {
  16. cout<<"i am family constuction!"<<endl;
  17. }
  18. son jack;
  19. };
  20. int main()
  21. {
  22. family happyfamily;
  23. //输出结果
  24. /*
  25. i am son constuction!
  26. i am family constuction!
  27. Press any key to continue
  28. */
  29. return 0;
  30. }

从上面的结果我们科看到,先调用的是构造函数。这是为什么?因为类中含有成员类时,先要给成员类申请空间,先调用成员类的构造函数,然后再调用自身的构造函数。

[cpp] view plaincopy

  1. #include <iostream>
  2. using namespace std;
  3. //父亲姓名
  4. class name
  5. {
  6. public:
  7. name()
  8. {
  9. cout<<"i am name constuction!"<<endl;
  10. }
  11. };
  12. //子类
  13. class base
  14. {
  15. public:
  16. base()
  17. {
  18. cout<<"i am base constuction!"<<endl;
  19. }
  20. };
  21. //父类
  22. class drived : public base
  23. {
  24. public:
  25. drived()
  26. {
  27. cout<<"i am drived constuction!"<<endl;
  28. }
  29. name drivedname;
  30. };
  31. int main()
  32. {
  33. drived d;
  34. //输出结果
  35. /*
  36. i am base constuction!
  37. i am name constuction!
  38. i am drived constuction!
  39. Press any key to continue
  40. */
  41. return 0;
  42. }

上面的例子是声明了一个name类,一个base类,一个drived类,其中drived类是从base类派生,且drived类中声明了name类的一个实例。

那么根据我们上面的分析,我们声明了drived类之后,先会调用父类构造函数,也就是输出i am base construction,然后调用自身的成员类构造函数,也就是i am name construction,最后调用自身的构造函数,也就是i am drived construction。

同理,如果我们在父类base类中声明了name成员类的话,顺序会是name->base->drived。我下面给出测试例子:

[cpp] view plaincopy

  1. #include <iostream>
  2. using namespace std;
  3. //父亲姓名
  4. class name
  5. {
  6. public:
  7. name()
  8. {
  9. cout<<"i am name constuction!"<<endl;
  10. }
  11. };
  12. //子类
  13. class base
  14. {
  15. public:
  16. base()
  17. {
  18. cout<<"i am base constuction!"<<endl;
  19. }
  20. name drivedname;
  21. };
  22. //父类
  23. class drived : public base
  24. {
  25. public:
  26. drived()
  27. {
  28. cout<<"i am drived constuction!"<<endl;
  29. }
  30. };
  31. int main()
  32. {
  33. drived d;
  34. //输出结果
  35. /*
  36. i am name constuction!
  37. i am base constuction!
  38. i am drived constuction!
  39. Press any key to continue
  40. */
  41. return 0;
  42. }

版权声明:本文为【借你一秒】原创文章,转载请标明出处。

时间: 2024-10-26 05:34:36

C++中类的构造函数调用顺序的相关文章

java初始化构造函数调用顺序

类初始化时构造函数调用顺序: (1)初始化对象的存储空间为零或null值:  (2)调用父类构造函数:  (3)按顺序分别调用类成员变量和实例成员变量的初始化表达式:  (4)调用本身构造函数. 例子:public class Dollar extends Money{     Rmb r=new Rmb()     public Dollar(){      System.out.println("Dollar is construct!");     }     public st

C++多重继承构造函数调用顺序

//以典型实例说明 1 class B1{}; 2 class V1:public B1(); 3 class D1:virtual public V1(); 4 class B2{}; 5 class B3{}; 6 class V2:public B1,publicB2{}; 7 class D2:virtual public V2,public B3{}; 8 class M1{}; 9 class M2{}; 10 class X:public D1,public D2 11 { 12

C++中构造函数调用顺序

C++中若某类a从基类b.虚基类c派生而来,且该类中具有对象成员d,则在构造该类的对象时执行构造函数的顺序? 构造一个类的对象的一般顺序是:class a:public b, virtual public c{}; 1.如果该类有直接或间接虚基类,先执行虚基类的构造函数: 2.如果该类有其他基类,按照他们在继承声明列表中出现的顺序分别执行构造函数,但是不再执行它们的虚基类的构造函数. 3.按照在类定义中出现的顺序,对派生类中新增的成员对象进行初始化. 4.执行构造函数函数体. 所以本题构造函数执

C++构造函数调用顺序

http%3A%2F%2F1.1%E6%96%B0%E5%BB%BA%E4%BC%9A%E8%AF%9D%E5%A4%B1%E8%B4%A5 http://index.ttplayer.com/songlist/502663901 http://list.mp3.baidu.com/songlist/502212235 http://list.mp3.baidu.com/songlist/502173428 http://list.mp3.baidu.com/songlist/502783840

继承中的构造析构函数调用顺序

子类构造函数必须堆继承的成员进行初始化: 1. 通过初始化列表或则赋值的方式进行初始化(子类无法访问父类私有成员) 2. 调用父类构造函数进行初始化 2.1  隐式调用:子类在被创建时自动调用父类构造函数(只能调用父类的无参构造函数和使用默认参数的构造函数) 2.2  显示调用:在初始化列表调用父类构造函数(适用所有的父类构造函数) #include <iostream> #include <string> using namespace std; class PParent //

虚函数析构函数调用顺序

析构函数参考:http://blog.csdn.net/zengchen__acmer/article/details/22592195?utm_source=tuicool构造函数参考:http://www.cnblogs.com/nliao/archive/2012/02/05/2339175.html C++构造函数调用顺序: 1.创建派生类的对象,基类的构造函数函数优先被调用(也优先于派生类里的成员类,多继承时,按照派生表的顺序依次调用): 2.如果类里面有成员类,成员类的构造函数优先被

c++深/浅拷贝 &amp;&amp; 构造函数析构函数调用顺序练习题

1.深/浅拷贝 编译器为我们提供的合成拷贝构造函数以及合成的拷贝赋值运算符都是浅拷贝.浅拷贝只是做简单的复制,如果在类的构造函数中new出了内存,浅拷贝只会简单的复制一份指向该内存的指针,而不会再开辟内存,这就会使得程序运行出现内存错误,如此,当对象析构的时候,会delete多次同一块内存区域,发生错误.这也就是为什么,必要的时候需要我们自己编写拷贝构造函数和重载赋值运算符,让它变成深拷贝,深拷贝即在copy指针的时候不是简单做值copy,而是还要开辟内存. 2.构造函数析构函数调用顺序练习题

C++中构造函数调用构造函数

今天想做道矩阵的题目时,却卡在一些编程细节上了,找了好久才发现原来是在构造函数处出了问题,然后上网百度了下,发现这篇文章说得很好:从一道题谈C++中构造函数调用构造函数,很棒! 还补充一点: 看来自己C++的基本功还有待提高啊~~

Swift 2.0学习笔记(Day 42)——构造函数调用规则

原创文章,欢迎转载.转载请注明:关东升的博客 在构造函数中可以使用构造函数代理帮助完成部分构造工作.类构造函数代理分为横向代理和向上代理,横向代理只能在发生在同一类内部,这种构造函数称为便利构造函数.向上代理发生在继承的情况下,在子类构造过程中,要先调用父类构造函数初始化父类的存储属性,这种构造函数称为指定构造函数. 构造函数调用规则 Person和Student类示例: class Person { var name: String var age: Int func description(