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

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

(A(number)); 或者 static_cast<A>(number); - jrok
这里有更多内容:https://dev59.com/rmgt5IYBdhLWcg3w8h_e。 - jrok
https://ideone.com/QbTf1t - BoBTFish
太酷了,谢谢!那么,我需要使用以下语句解决这个问题吗?A( (int)number ); - user2664344
1个回答

1
你的意图是创建一个临时对象,但这个对象也将是匿名的: 分号后你将无法引用它。没有必要创建一个匿名的临时对象然后立即舍弃它。你必须直接在调用构造函数/方法的地方实例化你的临时对象。
解决方案:
为了将匿名临时对象传递给函数,你需要在参数列表中实例化它:
functionExpectingA(A(number));

对于 "c declaration" 这一行,您正在挑战 最令人困惑的解析。如果您实际上需要将默认构造的 A 对象作为参数传递给另一个对象的构造函数,则需要添加另一对括号来完成此操作(以便编译器可以将其与函数声明区分开):
class OtherClass
{
public:
    OtherClass(A a)
    {
         //...
    };
};

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

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

如果您需要传递一个使用参数构建的匿名临时对象,则仍需要在匿名对象构造周围加上括号,这样就没有歧义了(因此不需要额外的括号)

OtherClass obj((A(number)));

C语言遗产:单个参数不足以解决问题

编辑#2:"为什么将一个单一的参数传递给构造函数不能解决歧义"。

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.

那么如果构造函数有更多参数呢?

如果您向 OtherClass 添加了一个接受两个(或更多)参数的构造函数:

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

然后是这个语法:

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

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

最后一段是错误的。OtherClass obj(A(number));也是一个函数声明。 - jrok
@jrok:谢谢你发现了这个问题! - Ad N

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接