4

我面临一个非常令人费解的问题。我正在尝试使用变量作为参数来构造对象。

请看一下这段代码:

#include <iostream>

class A {

  public:
    A()      : val(0) {};
    A(int v) : val(v) {};

  private:
    int val;
};

main() {

  int number;

  A a;       /* GOOD, object of type A, created without arguments */
  A b(2);    /* GOOD, object of type A, created with one argument */
  A c();     /* BAD, C++ thinks this is declaration of
                a function returning class A as a type */
  A(d);      /* GOOD, object of type A again; no arguments */
  A(number); /* BAD, tries to re-declare "number" as object of type A */
}

我想我确实理解为什么可以创建对象“a”、“b”和“d”,而其他对象则不能。

但我真的需要最后一个声明的语法,即

    A(number);

创建一个临时对象,作为参数传递给另一个对象。

知道如何解决它吗?

Kind regards
4

1 回答 1

1

您的意图是创建一个临时对象,但该对象将是匿名的:您无法在分号后引用它。创建匿名临时对象只是为了丢弃它是没有意义的。您必须直接在将使用它的 ctor/方法的调用站点实例化您的临时文件。

解决方案

要将匿名临时对象传递给函数,您实际上需要在参数列表中实例化它:

functionExpectingA(A(number));

对于“c 声明”这一行,您正在戳最令人头疼的 parse。如果您确实需要将默认构造A的对象作为参数传递给另一个对象构造函数,则需要添加另一对大括号来完成此操作(以便编译器可以将其与函数声明区分开来):

class OtherClass
{
public:
    OtherClass(A a)
    {
         //...
    };
};

OtherClass obj((A()));
               ^   ^

编辑#1jrok指出给A构造函数的参数不足以解决歧义。

如果您需要传递使用参数构建的匿名临时对象,则没有歧义(因此不需要额外的括号),您仍然需要围绕匿名对象构造的括号。:

OtherClass obj((A(number)));

C遗产:单一的论点是不够的

编辑#2:“为什么给 A 构造函数一个参数不能解决歧义”。

会发生什么OtherClass obj(A(number));
这是一个名为 的函数的声明obj,将一个A对象作为其唯一参数。这个参数被命名为 number。
即:它完全等同于OtherClass obj(A number);. 当然,您可以在函数声明时省略参数名称。所以它在语义上也等价于OtherClass obj(A);

对象名称周围带括号的语法继承自 C

int(a); // declares (and defines) a as an int.
int a;  // strictly equivalent.

那么构造函数的参数更多呢?

如果您添加了一个 ctor 来OtherClass获取两个(或更多)参数:

    OtherClass(A a1, A a2)
    {
         //...
    };

然后这个语法:

A arg1, arg2;
OtherClass obj(A(arg1, arg2));

这次是否会实际声明objOtherClass.
这是因为A(arg1, arg2)不能解释为A. 所以它实际上被解析为匿名A对象的构造,使用带有2个参数的构造函数。

于 2013-08-08T13:08:55.520 回答