C ++幽灵般的构造函数

时间:2011-12-12 14:29:56

标签: c++ constructor most-vexing-parse

  

可能重复:
  Why is it an error to use an empty set of brackets to call a constructor with no arguments?

让我们有这个代码

class Foo {
  Foo(int) { }
};

然后我们有结果:

int main() {
  Foo f1 = Foo(5); // 1: OK, explicit call
  Foo f2(5); // 2: OK, implicit call
  Foo f3(); // 3: no error, "f3 is a non-class type Foo()", how so?
  Foo f4(f1); // 4: OK, implicit call to default copy constructor
  Foo f5; // 5: expected error: empty constructor missing
}

你能解释一下 3 的情况吗?

6 个答案:

答案 0 :(得分:12)

第三行被解析为声明一个不带参数的函数并返回Foo

答案 1 :(得分:8)

Foo f3();声明一个名为f3的函数,返回类型为Foo

答案 2 :(得分:5)

C ++有一条规则,即如果一个语句可以被解释为一个函数声明,它就会以这种方式解释。

因此语法Foo f3();实际上声明了一个不带参数并返回Foo的函数。通过编写Foo f3;来解决这个问题,它也会调用默认的构造函数(当然,如果有的话)。

答案 3 :(得分:4)

  • f1在显式调用后调用复制构造函数,你在这一个
  • 上错了
  • f2是一个显式的构造函数调用//你在这里也错了
  • f3声明一个函数
  • f4再次是复制构造函数,例如f1 //你就在这里
  • f5会调用默认构造函数//再次就在这里

答案 4 :(得分:3)

这不是你想象的那样:

 Foo f3();

您可能认为这是对默认构造函数的显式调用,但事实并非如此。它实际上是一个名为f3的函数的声明,它不接受任何参数并按值返回Foo

将其解析为函数声明而不是构造函数调用称为Most Vexing Parse

答案 5 :(得分:2)

你已经定义了一个名为f3的函数,在第3例中返回一个foo。在第5例中,你没有定义默认的构造函数,所以你得到一个错误。