一旦我知道这个主题属于哪个主题,我会很乐意将这个主题的标题更改为更合适的内容。
如果我更改了导致错误的构造函数的参数,则没有错误。
如果我包含那个确切的构造函数,则只会出现此错误:
error: no matching function for call to 'Object::Object(Object)'
note: candidates are: Object::Object(Object&)
note: Object::Object()
代码:
#include <iostream>
using namespace std;
class Object {
public:
Object() {} /* default constructor - no problems at all */
Object( Object & toCopy ) {} /* Cause of error, but no error when commented out */
Object func() {
Object obj;
return obj;
}
};
int main() {
Object o = o.func(); /* this is the line that the error is actually on */
return 0;
}
答案 0 :(得分:6)
你已经声明了一个不寻常且可怕的复制构造函数,即通过非常量引用获取参数的复制构造函数。这是可能的,这意味着不会隐式定义其他复制构造函数。但是,这也意味着您无法从临时值构造副本,因为它们不会绑定到非常量引用。
除非你有理由做你正在做的事情(也许你想定义auto_obj
:-)?),你应该用参数Object const &
声明通常的复制构造函数(但要确保正确地定义它!),或者只是完全保留它并依赖于隐式生成的版本(就像你在代码中“注释掉行”时所发生的那样);或者在C ++ 11中,您可以通过声明Object(Object const &) = default;
默认复制构造函数。
(请注意,流行的Rule of Three表示您不应该定义自己的,非平凡的复制构造函数,或者如果您这样做,那么您还需要一个用户定义的析构函数和赋值运算符。确保您的代码是理智的。)
答案 1 :(得分:1)
你得到的错误
error: no matching function for call to 'Object::Object(Object)'
note: candidates are: Object::Object(Object&)
note: Object::Object()
表示编译器正在为类Object
寻找适当的复制构造函数。您的类定义中没有这样的函数:您的版本不能用于绑定临时(见下文)。正确的版本可能由您自己定义:
Object(const Object& orig) {
// and initialize data here, and return
}
或者你可以不声明这样的功能,并且将自动生成工作版本,因此也没有错误。
请注意:
您正在尝试定义Object( Object & toCopy ) {}
。这是不正确的,因为对临时进行非const引用意味着您无法使用此临时对象在构造函数中从中创建副本,因为临时对象无法分配给非const引用。
所以要表达这种不同的方式:
- &GT;编译器正在搜索复制构造函数
- &GT;找到你的版本
- &GT;这个版本告诉我:我不会这样做
最后:
Object o = o.func();
这不是个好主意。提到未构造或已经被破坏的物体的非静态成员是undefined behavior。将func()
设为静态,以便像Object::func()
一样使用,或者在正确构造的对象上调用它。
答案 2 :(得分:0)
尝试对象(const Object&amp; toCopy){}
答案 3 :(得分:0)
正如之前许多人已经指出的那样,问题是你只定义了一个带有引用的复制构造函数,但是o.func();
的调用返回是{{3} },只能绑定到右值引用或 const引用,而不能绑定到常规引用。
但是,您的代码还有另一个问题,在func()
上调用o
,此时该文件尚未初始化为rvalue。也许你打算实施工厂用语?在这种情况下,我建议您声明Object func();
静态,并从Object
范围内调用它,如下所示:
Object o = Object::func();