当前位置:   article > 正文

【C++笔记】C++继承与派生中的构造函数_can not be used when making a shared object;recomp

can not be used when making a shared object;recompile with -fpic csdn

C++中,构造函数与父类的其它成员(成员变量和成员方法)不同,它不能被子类继承。因此,在创建子类对象时,为了初始化从父类中继承来的成员变量,编译器需要调用其父类的构造函数。

关于子类中构造函数的构造原则,可分为以下4种情况分别来看:

1. 父类没有声明构造函数

  (1) 子类也没有声明自己的构造函数,则父类和子类均由编译器生成默认的构造函数。

  (2) 子类中声明了构造函数(无参或者带参),则子类的构造函数可以写成任何形式,不用顾忌父类的构造函数。在创建子类对象时,先调用父类默认的构造函数(编译器自动生成),再调用子类的构造函数。

2. 父类只声明了无参构造函数

   如果子类的构造函数没有显式地调用父类的构造,则将会调用父类的无参构造函数。也就是说,父类的无参构造函数将会被隐式地调用。

3. 父类只声明了带参构造函数

因为父类只有带参的构造函数,所以如果子类中的构造函数没有显示地调用父类的带参构造函数,则会报错,所以必需显示地调用。除非父类带参的构造函数的参数有默认值。

  1. //
  2. // test_extend.cpp
  3. // TestProject
  4. //
  5. #include <stdio.h>
  6. #include <iostream>
  7. using namespace std;
  8. class SuperClass1
  9. {
  10. public:
  11. SuperClass1(int i){
  12. cout<<"Constructing SuperClass with param i "<<i<< endl;
  13. }
  14. };
  15. class SubClass :public SuperClass1
  16. {
  17. public:
  18. //compile error,Constructor for 'SubClass' must explicitly initialize the base class 'SuperClass1' which does not have a default constructor
  19. //SubClass(int i){}
  20. //compile ok
  21. SubClass(int i):SuperClass1(i){}
  22. };
  23. int main()
  24. {
  25. SubClass s(3);
  26. }

运行结果如下:

  1. Constructing SuperClass with param i 3
  2. Program ended with exit code: 0

 

4. 父类同时声明了无参和带参构造函数

在这种情况下,子类只需要实现父类的一个构造函数即可,不管是无参的还是带参的构造函数。

如果子类的构造函数没有显示地调用父类的构造函数(无参或带参),则默认调用父类的无参构造函数。

子类当然也可以显式调用父类的带参构造函数

  1. //
  2. // test_extend.cpp
  3. // TestProject
  4. //
  5. #include <stdio.h>
  6. #include <iostream>
  7. using namespace std;
  8. class SuperClass1
  9. {
  10. public:
  11. SuperClass1(){
  12. cout<<"Constructing SuperClass no param "<<endl;
  13. }
  14. SuperClass1(int i){
  15. cout<<"Constructing SuperClass with param i "<<i<< endl;
  16. }
  17. };
  18. class SubClass :public SuperClass1
  19. {
  20. public:
  21. //compile error,Constructor for 'SubClass' must explicitly initialize the base class 'SuperClass1' which does not have a default constructor
  22. SubClass(){}
  23. //compile ok
  24. SubClass(int i):SuperClass1(i){}
  25. };
  26. int main()
  27. {
  28. SubClass s;
  29. SubClass s2(3);
  30. }

运行结果如下:

  1. Constructing SuperClass no param
  2. Constructing SuperClass with param i 3
  3. Program ended with exit code: 0

初始化过程中,初始化的执行顺序是:

1.先调用基类构造器,初始化基类成员。调用顺序按照它们被继承时的顺序(从左至右)

2.再找初始化列表指定的初始化子类新成员对象。调用顺序按照它们在类中声明的顺序,与构造函数初始化列表里的书写顺序无关

3.最后才执行子类构造器中的函数体

其中,如果派生类中新增成员中有内嵌的对象,第二步调用才会执行,否则,就直接跳转到第三步。

 

  1. //
  2. // test_extend.cpp
  3. // TestProject
  4. //
  5. #include <stdio.h>
  6. #include <iostream>
  7. using namespace std;
  8. class SuperClass1
  9. {
  10. public:
  11. SuperClass1(int i){
  12. cout<<"Constructing SuperClass 1 "<<i<< endl;
  13. }
  14. };
  15. class SuperClass2
  16. {
  17. public:
  18. SuperClass2(int j){
  19. cout<<"Constructing SuperClass 2 "<<j<< endl;
  20. }
  21. };
  22. class SuperClass3
  23. {
  24. public:
  25. SuperClass3(){
  26. cout<<"Constructing SuperClass 3 "<< endl;
  27. }
  28. };
  29. class SubClass : public SuperClass2,public SuperClass1,public SuperClass3
  30. {
  31. public:
  32. SubClass(int a,int b, int c,int d):SuperClass1(a),s2(d),s1(c),SuperClass2(b){
  33. i = 100;
  34. cout<<"Constructing SubClass i "<< i << endl;
  35. }
  36. private:
  37. SuperClass1 s1;
  38. SuperClass2 s2;
  39. SuperClass3 s3;
  40. int i;
  41. };
  42. int main()
  43. {
  44. //1.SubClass从左到右依次继承了SuperClass2,SupClass1,SuperClass3,所以先执行SuperClass2的构造函数(SuperClass2(b)),然后执行SuperClass3的构造函数(默认构造函数),然后执行SuperClass1的构造函数(SuperClass1(a))
  45. //2.再执行成员变量的初始化,先是s1(s1(c)),然后s2(s2(b)),最后s3,由于s3成员变量对应的类是默认构造函数,所以不需要传参数,s1,s2都必须在SubClass的构造函数初始化列表中,显示初始化
  46. //3.最后执行构造函数体中的代码,i=100
  47. SubClass obj(1,2,3,4);
  48. return 0;
  49. }

执行结果:

  1. Constructing SuperClass 2 2
  2. Constructing SuperClass 1 1
  3. Constructing SuperClass 3
  4. Constructing SuperClass 1 3
  5. Constructing SuperClass 2 4
  6. Constructing SuperClass 3
  7. Constructing SubClass i 100
  8. Program ended with exit code: 0

参考链接:

https://blog.csdn.net/sevenjoin/article/details/82222895

https://www.jianshu.com/p/6cabb9e27d58

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/224448
推荐阅读
相关标签
  

闽ICP备14008679号