4

我已将问题简化为以下代码:

#include<iostream>
#include<stdio.h>
#include <list>
using namespace std;
class B
{
public:
    B(){
        cout<<"Default ctor of B"<<endl;
    };
};

class C
{
public:
    C()
    {
        cout<<"Default ctor of C"<<endl;
    }
    void sayHello()
    {
        cout<<"Say hello"<<endl;
    }
};
class A: public B
{
public:
    void fun()
    {
        c.sayHello();
    }
private:
    C c;
};

int main(int argc, char** argv)
{
    A* a=new A();
    a->fun();
    delete a;
    return 0;
}

当我创建 A 的对象时,我可以看到 C 的默认构造函数没有被调用,但是当我调用 A::fun() 时,它会正确调用 C::sayHello()。这怎么可能?我在特定的工具链下交叉编译它,但仍然如何分配对象内存而不调用它的默认 ctor 主体?这似乎是明显的编译器错误,不是吗?

当我在 Fedora 上使用 GCC 编译上述代码时,一切都按预期工作......

编辑:编译器是为 Broadcom 芯片组量身定制的 GCC-4.2。执行代码时,嵌入式系统存在问题。解决它的方法是将默认的空构造函数添加到 A:

A(){}

即使没有在其初始化列表上显式调用 C 成员的默认构造函数。

4

1 回答 1

1

@juanchopanza 是正确的,懒惰地调用 C 的 ctor 不是编译器符合标准的行为。“一个对象在其构造函数完成之前不被认为是构造的。” (Stroustrup,C++ 编程语言,第 3 版,第 366 页)。

然而,这里可能还有另一个微妙之处,即默认构造函数和所谓的值初始化之间的区别。请参阅这两个以前的 StackOverflow 答案:

根据您的编译器是否将 C 视为 POD 类型,以及它是否符合 C++98 或 C++03 标准,它可能正在执行值初始化而不是默认 ctor。将用户声明的默认 ctor 添加到 A 会改变行为这一事实表明该问题正在发挥作用。

于 2013-11-06T17:06:38.217 回答