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

Constructor is not called in this aggregation class

本文关键字:调用 构造函数      更新时间:2023-10-16
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 */
}

不会为上述代码生成任何输出。这是由于此链接中讨论的编译器优化(复制省略)吗?

但是如果我有一个 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()
}

添加一对额外的括号:

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

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

[编辑]

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

[编辑]

在这种情况下,Clang 实际上更有帮助,并给出了使用部分的提示:

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 条警告。

B b(A());

不明确,可以解释为变量声明或函数的声明,该函数返回类型为 B 的 restult,并采用没有参数的函数类型的单个未命名参数并返回类型 A 的结果。虽然你可能认为第一个应该发生,但标准规定实际上第二个会发生。请参阅维基百科中有关最烦人的解析的文章。

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

A a;
B  b(a);