我一直认为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
怎么样?
答案 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;