从子类的构造函数体调用基类的构造函数

TT_*_*TT_ 9 c++ constructor base-class

我觉得这是不可能的,例如: 在C++中的其他一些指令之后调用基类的构造函数
但是下面的程序运行并生成两行"Constructor Person":

#include <iostream>

class Person
{
public:
    Person() 
    { 
        std::cout << "Constructor Person" << std::endl; }
    };

class Child : public Person
{
public:
    Child() 
    { 
        c = 1; 
        Person(); 
    }
    int c;
};

int main() 
{
    Child child;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

第一个是默认构造函数的隐式调用,这是明确的.第二个怎么样 - 这是否意味着标题中描述的行为是合法的?我使用Visual C++ 2010.

zda*_*dan 12

子类构造函数内部的调用不是调用基类构造函数,而是创建一个类型为Person的临时,未命名和新对象.它将在构造函数退出时被销毁.为了澄清,您的示例与执行此操作相同:

Child() { c = 1; Person tempPerson; }
Run Code Online (Sandbox Code Playgroud)

除了在这种情况下,临时对象具有名称.

如果你稍微修改你的例子,你可以看到我的意思:

class Person
{
public:
    Person(int id):id(id) { std::cout << "Constructor Person " << id << std::endl; }
    ~Person(){ std::cout << "Destroying Person " << id << std::endl; }
    int id;
};

class Child : public Person
{
public:
    Child():Person(1) { c = 1; Person(2); }
int c;
};

int main() {
Child child;

Person(3);
return 0;
}
Run Code Online (Sandbox Code Playgroud)

这会产生输出:

Constructor Person 1
Constructor Person 2
Destroying Person 2
Constructor Person 3
Destroying Person 3
Destroying Person 1
Run Code Online (Sandbox Code Playgroud)


Mar*_*som 6

您不能从子构造函数的主体调用它,但您可以将它放入初始化列表中:

public:
    Child() : Person() { c = 1; }
Run Code Online (Sandbox Code Playgroud)

当然,调用父项的默认构造函数没有帮助,因为这会自动发生.如果需要将参数传递给构造函数,它会更有用.

你无法从正文中调用构造函数的原因是因为C++保证父元素将在子构造函数启动之前完成构造.


TT_*_*TT_ 6

以下是"Accelerated C++"的摘录:"派生对象由以下构造:
1.为整个对象分配空间(基类成员以及派生类成员);
2.调用基类构造函数初始化基础- 对象的 - 类部分;
3.按构造函数初始化程序的指示初始化派生类的成员;
4.执行派生类构造函数的主体(如果有).

总结答案和注释:从子类的构造函数体中调用基类的构造函数是不可能的,因为上面的#2必须在#4之前.但是我们仍然可以在派生的构造函数体中创建一个基础对象,从而调用一个基础构造函数.它将是一个与使用当前执行的派生构造函数构造的对象不同的对象.