C ++:如何将变量作为参数传递给类构造函数

时间:2013-08-08 12:15:36

标签: c++ variables arguments

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

请看一下这段代码:

#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

1 个答案:

答案 0 :(得分:1)

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

解决方案

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

functionExpectingA(A(number));

对于“c声明”这一行,你正在寻找most vexing parse。如果您确实需要将默认构造的A对象作为参数传递给另一个对象构造函数,则需要添加另一对大括号来执行该操作(因此编译器可以将其与函数声明区分开来):

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

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

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

如果你需要传递一个用参数构建的匿名临时对象,没有歧义(所以不需要额外的括号),你仍然需要围绕匿名对象构造的括号:

OtherClass obj((A(number)));

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

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

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

The syntax with parentheses around the object name is inherited from C

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

那么构造函数的参数是多少呢?

如果您向OtherClass添加了一个ctor,其中包含两个(或更多)参数:

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

然后这句法语:

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

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