Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 转换构造函数_C++_Constructor_Type Conversion_Constants_Copy Constructor - Fatal编程技术网

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) {}