赞
踩
C++中,构造函数与父类的其它成员(成员变量和成员方法)不同,它不能被子类继承。因此,在创建子类对象时,为了初始化从父类中继承来的成员变量,编译器需要调用其父类的构造函数。
1. 父类没有声明构造函数
(1) 子类也没有声明自己的构造函数,则父类和子类均由编译器生成默认的构造函数。
(2) 子类中声明了构造函数(无参或者带参),则子类的构造函数可以写成任何形式,不用顾忌父类的构造函数。在创建子类对象时,先调用父类默认的构造函数(编译器自动生成),再调用子类的构造函数。
2. 父类只声明了无参构造函数
如果子类的构造函数没有显式地调用父类的构造,则将会调用父类的无参构造函数。也就是说,父类的无参构造函数将会被隐式地调用。
3. 父类只声明了带参构造函数
因为父类只有带参的构造函数,所以如果子类中的构造函数没有显示地调用父类的带参构造函数,则会报错,所以必需显示地调用。除非父类带参的构造函数的参数有默认值。
- //
- // test_extend.cpp
- // TestProject
- //
-
- #include <stdio.h>
- #include <iostream>
- using namespace std;
-
- class SuperClass1
- {
- public:
- SuperClass1(int i){
- cout<<"Constructing SuperClass with param i "<<i<< endl;
- }
- };
-
-
- class SubClass :public SuperClass1
- {
- public:
- //compile error,Constructor for 'SubClass' must explicitly initialize the base class 'SuperClass1' which does not have a default constructor
- //SubClass(int i){}
-
- //compile ok
- SubClass(int i):SuperClass1(i){}
- };
-
- int main()
- {
- SubClass s(3);
- }
运行结果如下:
- Constructing SuperClass with param i 3
- Program ended with exit code: 0
4. 父类同时声明了无参和带参构造函数
在这种情况下,子类只需要实现父类的一个构造函数即可,不管是无参的还是带参的构造函数。
如果子类的构造函数没有显示地调用父类的构造函数(无参或带参),则默认调用父类的无参构造函数。
子类当然也可以显式调用父类的带参构造函数
- //
- // test_extend.cpp
- // TestProject
- //
-
- #include <stdio.h>
- #include <iostream>
- using namespace std;
-
- class SuperClass1
- {
- public:
- SuperClass1(){
- cout<<"Constructing SuperClass no param "<<endl;
- }
-
- SuperClass1(int i){
- cout<<"Constructing SuperClass with param i "<<i<< endl;
- }
- };
-
-
- class SubClass :public SuperClass1
- {
- public:
- //compile error,Constructor for 'SubClass' must explicitly initialize the base class 'SuperClass1' which does not have a default constructor
- SubClass(){}
-
- //compile ok
- SubClass(int i):SuperClass1(i){}
- };
-
- int main()
- {
- SubClass s;
- SubClass s2(3);
- }
运行结果如下:
- Constructing SuperClass no param
- Constructing SuperClass with param i 3
- Program ended with exit code: 0
1.先调用基类构造器,初始化基类成员。调用顺序按照它们被继承时的顺序(从左至右)
2.再找初始化列表指定的初始化子类新成员对象。调用顺序按照它们在类中声明的顺序,与构造函数初始化列表里的书写顺序无关
3.最后才执行子类构造器中的函数体
其中,如果派生类中新增成员中有内嵌的对象,第二步调用才会执行,否则,就直接跳转到第三步。
- //
- // test_extend.cpp
- // TestProject
- //
-
- #include <stdio.h>
- #include <iostream>
- using namespace std;
-
- class SuperClass1
- {
- public:
- SuperClass1(int i){
- cout<<"Constructing SuperClass 1 "<<i<< endl;
- }
- };
-
- class SuperClass2
- {
- public:
- SuperClass2(int j){
- cout<<"Constructing SuperClass 2 "<<j<< endl;
- }
- };
-
- class SuperClass3
- {
- public:
- SuperClass3(){
- cout<<"Constructing SuperClass 3 "<< endl;
- }
- };
-
- class SubClass : public SuperClass2,public SuperClass1,public SuperClass3
- {
- public:
- SubClass(int a,int b, int c,int d):SuperClass1(a),s2(d),s1(c),SuperClass2(b){
- i = 100;
- cout<<"Constructing SubClass i "<< i << endl;
- }
-
- private:
- SuperClass1 s1;
- SuperClass2 s2;
- SuperClass3 s3;
-
- int i;
- };
-
- int main()
- {
- //1.SubClass从左到右依次继承了SuperClass2,SupClass1,SuperClass3,所以先执行SuperClass2的构造函数(SuperClass2(b)),然后执行SuperClass3的构造函数(默认构造函数),然后执行SuperClass1的构造函数(SuperClass1(a))
- //2.再执行成员变量的初始化,先是s1(s1(c)),然后s2(s2(b)),最后s3,由于s3成员变量对应的类是默认构造函数,所以不需要传参数,s1,s2都必须在SubClass的构造函数初始化列表中,显示初始化
- //3.最后执行构造函数体中的代码,i=100
- SubClass obj(1,2,3,4);
- return 0;
- }
执行结果:
- Constructing SuperClass 2 2
- Constructing SuperClass 1 1
- Constructing SuperClass 3
- Constructing SuperClass 1 3
- Constructing SuperClass 2 4
- Constructing SuperClass 3
- Constructing SubClass i 100
- Program ended with exit code: 0
参考链接:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。