C++中,继承时,创建子类对象,能否在子类构造函数初始化列表里调用基类构造函数?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++中,继承时,创建子类对象,能否在子类构造函数初始化列表里调用基类构造函数?相关的知识,希望对你有一定的参考价值。

然后基类构造函数里直接初始化基类private成员??这一步在子类构造函数右边的初始化列表里进行?

//如果基类没有默认构造函数,则子类的构造函数必须要给定基类的构造函数参数。因为,在类的实例化时是先执行基类构造函数在执行子类构造函数。子类构造函数初始化列表后面直接列出基类构造函数即可,系统会自动调用,不用用户调用。
class A
public:
A(int x,int y):x(x),y(y)
private:
int x; int y;
;
class B:public A
public:
B(int x,int y,int z):A(x,y),z(z) //子类构造函数初始化列表必须给出基类所需参数
;
参考技术A 不能,你自己写的构造函数体,是在初始化列表执行之后才执行,也就是如果不写在列表里,就会调用默认构造函数构造基类对象部分。追问

不能?为什么?

初始化列表当然是先执行的,这跟不能有什么关系?

追答

你在函数体里面再写的话,等于给基类部分构造两次,肯定不对啊,要是想重新赋值,那直接用语句,不能再用构造函数了。

C++调用父类的构造函数规则

构造方法用来初始化类的对象,与父类的其它成员不同,它不能被子类继承(子类可以继承父类所有的成员变量和成员方法,但不继承父类的构造方法)。因此,在创建子类对象时,为了初始化从父类继承来的数据成员,系统需要调用其父类的构造方法。

如果没有显式的构造函数,编译器会给一个默认的构造函数,并且该默认的构造函数仅仅在没有显式地声明构造函数情况下创建。

构造原则如下:
1. 如果子类没有定义构造方法,则调用父类的无参数的构造方法。

2. 如果子类定义了构造方法,不论是无参数还是带参数,在创建子类的对象的时候,首先执行父类无参数的构造方法,然后执行自己的构造方法。

3. 在创建子类对象时候,如果子类的构造函数没有显示调用父类的构造函数,则会调用父类的默认无参构造函数。

4. 在创建子类对象时候,如果子类的构造函数没有显示调用父类的构造函数且父类自己提供了无参构造函数,则会调用父类自己的无参构造函数。

5. 在创建子类对象时候,如果子类的构造函数没有显示调用父类的构造函数且父类只定义了自己的有参构造函数,则会出错(如果父类只有有参数的构造方法,则子类必须显示调用此带参构造方法)。

6. 如果子类调用父类带参数的构造方法,需要用初始化列表的方式。

结论:子类构造函数必须要调用父类的构造函数(无论显式还是隐式),本质原因在于继承的性质决定了必须先有父再有子!

 

看一个例子:在执行new A1时,下面代码的输出是什么

#include <iostream>
using namespace std;

int init(const std::string & info)
{
    std::cout << info << std::endl;
    return 0;
}

class A
{
    int m_x;
public:
    A():m_x(init("Init A::m_x"))
    {
        init("Call A::A()");
    }
};
class A1:public A
{
    int m_x;
    int m_y;
public:
    A1(): m_y(init("Init A1::m_y")), m_x(init("Init A1::m_x"))
  { 
    init(
"Call A1::A1()");
  }
};
打印出来的结果为:

Init A::m_x
Call A::A()  ==>是因为隐式调用了父类的构造函数
Init A1::m_x ==>按照成员变量的声明顺序“而非”初始化列表指定的顺序来进行构造
Init A1::m_y
Call A1::A1()

参考:

http://www.cnblogs.com/sunada2005/p/3396585.html

http://blog.csdn.net/scottly1/article/details/25594439

以上是关于C++中,继承时,创建子类对象,能否在子类构造函数初始化列表里调用基类构造函数?的主要内容,如果未能解决你的问题,请参考以下文章

C++调用父类的构造函数规则

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

C++中子类从基类都继承啥?

C++ 继承:子类实例同时使用子构造函数和父构造函数

在 C++ QObject 子类中调用析构函数之前执行操作

定义子类对象时要先调用基类构造函数,是应该哪样理解呢