隐式构造函数参数

时间:2012-02-16 02:20:21

标签: c++ class constructor

我一直认为C ++中的隐式构造函数只能是只有一个参数的构造函数。例如:

class Foo1
{
   Foo(int); // This could be an implicit constructor
};

但以下代码是正确的:

class Foo2
{
    Foo2(int, int=0);  // Would compiler use this as an implicit constructor?
}

我可以这样做:

Foo1 obj;
...
obj = 5;

Foo2怎么样?

4 个答案:

答案 0 :(得分:7)

首先,任何构造函数都可以标记为explicit。它有多少论点是无关紧要的。

有了这个,你现在需要了解explicit的真正含义。它只是意味着可以调用构造函数的唯一方法是显式指定类名:

struct foo
{
    foo(int){}
    explicit foo(double){}
};

void bar(foo){}

bar(5); // okay, calls foo(int) to construct the foo
bar(3.14); // error, cannot call foo(double) because foo was not explicitly used
bar(foo(3.14)); // okay, calls foo(double) to construct the foo

我们没有明确标记多参数构造函数的原因是因为它没用。给出:

struct baz
{
    baz(int, int, int);
};

除了说baz之外,你还能怎么称呼那个构造函数? (如baz(1, 2, 3)中所述。)†

在您的示例中,explicit是明智的,因为您只能使用一个参数调用该构造函数。你实际做的只取决于你是否认为它应该是可以隐式兑换的。


†这忽略了C ++ 11初始化列表。在C ++ 11中,我想你可以说:

void qaz(baz) {}

qaz({1, 2, 3}); 

并且设法获得一个隐式转换为多参数构造函数,但我不太了解初始化列表以做出有意义的注释,除非作为脚注。

答案 1 :(得分:2)

如果我明白你在问什么,那么答案是肯定的。

更具体地说,基本上只能用一个参数调用的任何 ctor都可以用于隐式转换。为了防止这种情况,可以将这样的ctor标记为explicit。这同样适用于只接受一个参数的ctor,或者可以接受多个参数的ctor,但是为其他参数提供默认值。

答案 2 :(得分:1)

你在这里混淆EXplicit和IMplicit。你所说的是转换构造函数。显式构造函数恰恰相反:可以用于(隐式)转换的构造函数。

并回答你的问题:是的,Foo2(int, int=0)是一个转换构造函数,可以在obj = 5中启用隐式转换,因为它可以使用一个int参数调用。

默认构造函数也是如此:如果为第一个参数添加默认值,它还将成为默认构造函数。

答案 3 :(得分:1)

你可能意味着隐式构造函数,而不是显式

无论如何,你不能这样做(与你认为的相反):

Foo1 obj; //this line will not compile as it takes one argument!
obj = 5;

我确定在你说你可以这样做之前你还没有编译你的代码。

但是,如果你是这个意思,

Foo1 obj(10); //OK now
obj = 5;

然后是的,你可以。

现在Foo2怎么样?好吧,如果Foo2也是you can do so

Foo2 foo(10);
foo = 5;