2

尝试编译代码:

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

4 回答 4

5

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

以下代码也可以编译(对构造函数的正确调用采用int*):

Foo foo(&i);

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

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

于 2013-05-27T07:46:49.847 回答
2

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

适当的复制构造函数将具有签名Foo(const Foo&)。注意const.

于 2013-05-27T07:46:37.900 回答
1
Foo foo = &i;

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

Foo foo = Foo(&i);

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

Foo(Foo const& other) {}
于 2013-05-27T15:25:07.143 回答
-3

Foo foo = &i 不会做你想的,试试 Foo foo=Foo(&i)

于 2013-05-27T07:42:47.520 回答