转换构造函数

时间:2013-05-27 07:41:50

标签: c++ constructor type-conversion const 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 ‘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时,为什么代码会编译?

谢谢!

4 个答案:

答案 0 :(得分:5)

您的第一个构造函数是一个复制构造函数,不能用于从临时文件中复制。为此,您需要添加const,因此签名变为Foo(const Foo&)

以下代码也编译(正确调用构造函数获取int*):

Foo foo(&i);

您的代码在赋值运算符的右侧创建一个(临时)对象Foo,然后将此对象(使用(缺少的)复制构造函数)分配给foo

编译器通常会自动为您生成一个复制构造函数,它接受一个const引用。但是,由于您定义了一个构造函数,它使用Foo&,编译器不会为您生成这样的复制构造函数。因此删除第一个构造函数也会使代码编译。

答案 1 :(得分:2)

这是因为编译器已经使用表达式Foo创建了&i的实例。然后它尝试将其复制到目标变量foo,但由于您没有正确的复制构造函数,因此无法正常工作。

正确的复制构造函数将具有签名Foo(const Foo&)。请注意const

答案 2 :(得分:1)

Foo foo = &i;

此行创建一个参数为Foo的临时&I对象。这是编译器将该行返回的内容:

Foo foo = Foo(&i);

然后它将尝试复制构造它无法执行的临时,因为您创建的构造函数Foo(Foo&)会覆盖复制构造函数。将以下构造函数添加到您的代码中以使其工作:

Foo(Foo const& other) {}

答案 3 :(得分:-3)

Foo foo =&我不会按你的想法行事,试试Foo foo = Foo(& i)