C++ 转换构造函数
正在尝试编译代码:C++ 转换构造函数,c++,constructor,type-conversion,constants,copy-constructor,C++,Constructor,Type Conversion,Constants,Copy Constructor,正在尝试编译代码: class Foo { public: Foo(Foo&){} Foo(int*){} }; int main() { int i = 2; Foo foo = &i; return 0; } 得到这个: prog.cpp: In function ‘int main()’: prog.cpp:11:16: error: no matching function for call to ‘Fo
class Foo
{
public:
Foo(Foo&){}
Foo(int*){}
};
int main()
{
int i = 2;
Foo foo = &i;
return 0;
}
得到这个:
prog.cpp: In function ‘int main()’:
prog.cpp:11:16: error: no matching function for call to ‘Foo::Foo(Foo)’
prog.cpp:11:16: note: candidates are:
prog.cpp:5:9: note: Foo::Foo(int*)
prog.cpp:5:9: note: no known conversion for argument 1 from ‘Foo’ to ‘int*’
prog.cpp:4:9: note: Foo::Foo(Foo&)
prog.cpp:4:9: note: no known conversion for argument 1 from ‘Foo’ to ‘Foo&’
我希望在Foo-Foo=&I
行上应该称为Foo(int*)
c-tor
为什么编译器尝试查找Foo::Foo(Foo)
c-tor
为什么它不直接使用当前的Foo(int*)
c-tor
当我将const
添加到第一个c-tor的参数时,为什么代码会编译
当我完全删除第一个c-tor时,为什么代码会编译
谢谢 Foo-Foo=&我不会做你想做的事,试试Foo-Foo=Foo(&i)这是因为编译器已经用表达式
&i
创建了Foo
的实例。然后,它尝试将其复制到目标变量foo
,但由于您没有合适的复制构造函数,它将无法工作
一个合适的复制构造函数应该有签名
Foo(constfoo&)
。注意常量
您的第一个构造函数是复制构造函数,不能用于从临时对象复制。为此,您需要添加const
,这样签名就变成Foo(constfoo&)
下面的代码也会编译(对构造函数的正确调用,使用int*
):
代码在赋值运算符的右侧创建一个(临时)对象Foo
,然后(使用(缺少的)复制构造函数)将该对象赋值给Foo
编译器通常会自动为您生成一个复制构造函数,该构造函数采用常量引用。但是,由于您使用Foo&
定义了一个构造函数,编译器不会为您生成这样一个副本构造函数。因此,删除第一个构造函数也会使代码编译
Foo foo = &i;
此行创建一个参数为&I
的临时Foo
对象。这是编译器将行返回到的内容:
Foo foo = Foo(&i);
然后,它将尝试复制临时构造函数,因为您创建的构造函数覆盖了复制构造函数,所以它无法复制临时构造函数。将以下构造函数添加到代码中以使其正常工作:
Foo(Foo const& other) {}
我想你需要
Foo(constfoo&){}
。或Foo-Foo(&i)代码>。这是,所以您需要一个有效的复制构造函数。请注意…复制构造函数的参数必须是const
@CaptainObvlious。我注意到,如果添加const
,代码将可以编译。但是无论如何,第1个c-tor不会在第Foo-Foo=&i
行上调用。那么为什么更改它的签名会影响代码呢?标准中还规定了。复制构造函数的参数必须是const
?谢谢。@Kolyunya它的名字实际上是——尽管是含蓄的。请看约阿希姆的回答。我应该用“按你所期望的那样工作”来修饰它。请参阅第12.8节-复制和移动对象签名指向非指针变量的指针也不起作用。看起来您今天可能会得到一个徽章;)你可以自己尝试一下,发现它不起作用。那么你能告诉我为什么代码只调用第二个c-tor吗?@Kolyunya我猜:如果允许复制,它就会编译。但是编译器发现它不是必需的。@Kolyunya副本可以省略,但必要的副本构造函数必须在编译时可用。用“适当”代替“适当”怎么样?它仍然是一个副本构造函数。@Kolyunya对副本构造函数的调用可以省略。这意味着对象将直接在目标空间中构造,而不是在临时空间中构造并复制到目标空间。下面是foof(Foo&i)的语义代码>变成了Foo f&i的代码代码>如果删除了副本。搜索“复制省略”以获取详细信息。由于省略始终是可选的,因此程序必须是完整的、非省略形式的合法程序。第一个ctor是复制ctor。它只是不能用于从临时文件中复制。参见C++11[class.copy]§2
;X&
、const X&
、volatile X&
和const volatile X&
都是类X
的有效复制参数,感谢澄清;我相应地编辑了我的答案。我发现一些有趣的事情,MS VC8.0编译器将删除Foo的临时对象,并使用“&I”来构造Foo,这样就不会调用复制构造函数,也不会抛出错误。甚至我在调试模式下编译它@里姆斯
Foo(Foo const& other) {}