在此聚合类中不调用构造函数

时间:2014-02-18 09:28:57

标签: c++

class A {
public:
    A() { cout << "A()" << endl; }
};
class B {
public:
    A a;
    B(const A& a1) : a(a1) { cout << "B(const A&)" << endl; }
    /* B(const A& a1) { a = a1; cout << "B(const A&)" << endl; } */
};
int main() {
    B b(A());  /* no ouput */
}

没有为上述代码生成输出。这是由于编译器优化(复制省略),如本link

中所述

但是如果我有一个B类构造函数并重写代码如下:

class A {
public:
    A() { cout << "A()" << endl; }
};
class B {
public:
    A a;
    B() {}
    B(const A& a1) : a(a1) { cout << "B(const A&)" << endl; }
    /* B(const A& a1) { a = a1; cout << "B(const A&)" << endl; } */
};
int main() {
    B().a; // gives output A()
}

3 个答案:

答案 0 :(得分:3)

添加一对额外的括号:

B b((A())); 

// you can also fix it using new C++11 initialization syntax:
B b{A()};

你面临的问题称为最烦恼的解析,这意味着编译器无法决定你是否需要函数声明或变量定义。

[编辑]

我还应该补充一点,标准要求编译器在这种情况下选择函数声明。

[编辑]

在这种情况下,

clang实际上更有帮助,并提示使用partentheses:

http://rextester.com/PECQ53431

source_file.cpp:16:8: warning: parentheses were disambiguated as a function declaration [-Wvexing-parse]
    B b(A());  /* no ouput */
       ^~~~~
source_file.cpp:16:9: note: add a pair of parentheses to declare a variable
    B b(A());  /* no ouput */
        ^
        (  )

生成1个警告。

答案 1 :(得分:1)

B b(A());

是不明确的,可以解释为变量声明或函数声明,返回类型为B的restult,并获取一个没有参数的函数类型的未命名参数,并返回结果输入A。虽然您可能认为应该首先执行标准,但事实上第二个将发生。请参阅维基百科中有关most vexing parse的文章。

答案 2 :(得分:0)

不是在创建B对象后创建A对象,而是在main中创建第一个A s对象。

A a;
B  b(a);