0

一旦我知道它属于哪个主题,我很乐意将这个线程的标题更改为更合适的名称。

如果我更改导致错误的构造函数的参数,则没有错误。

仅当我包含该确切的构造函数时才会发生此错误:

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;

}
4

4 回答 4

6

您已经声明了一个不寻常且可怕的复制构造函数,即通过非常量引用获取参数的构造函数。这是可能的,这意味着不会隐式定义其他复制构造函数。但是,这也意味着您不能从临时值构造副本,因为它们不会绑定到非常量引用。

除非你有理由去做你正在做的事情(也许你想定义auto_obj:-) ?),你应该用参数声明通常的复制构造函数Object const &(但要确保正确定义它!),或者完全忽略它并且依赖隐式生成的版本(当您在代码中“注释掉该行”时会发生这种情况);或者在 C++11 中,您可以通过声明来默认复制构造函数Object(Object const &) = default;.

(请注意,流行的三法则说您不应该定义自己的非平凡复制构造函数,或者如果您这样做,那么您还需要一个用户定义的析构函数和赋值运算符。确保您的代码是理智的。 )

于 2013-09-11T23:09:43.220 回答
1

你得到的错误

error: no matching function for call to 'Object::Object(Object)'
note: candidates are: Object::Object(Object&)
note:                 Object::Object()

意味着编译器正在为 class 寻找合适的复制构造函数Object。您的类定义中没有这样的功能:您的版本不能用于绑定临时(见下文)。正确的版本可能由您自己定义:

Object(const Object& orig) {
    // and initialize data here, and return 
}

或者你可以不声明这样的函数,工作版本会自动生成,这样也不会出错。


注意:您正在尝试定义Object( Object & toCopy ) {}. 这是不正确的,因为对临时对象进行非常量引用意味着您不能使用此临时对象在构造函数中从中创建副本,因为临时对象不能分配给非常量引用

所以要表达这种不同的方式:

-> 编译器正在寻找复制构造函数

-> 找到你的版本

-> 这个版本告诉我:我不会这样做

最后:

Object o = o.func();

这不是个好主意。引用尚未构造或已销毁的对象的非静态成员是未定义的行为。将其设为func()静态,以便像Object::func()在正确构造的对象上一样使用或调用它。

于 2013-09-11T23:19:10.853 回答
0

正如之前许多人已经指出的那样,问题在于您只定义了一个带引用的复制构造函数,但调用的返回o.func();是一个右值,它只能绑定到右值引用const 引用,不能绑定到常规引用

但是,您的代码还有另一个问题,调用func()on o,此时它是一个尚未初始化的对象,是一个非常糟糕的主意。也许您打算实现工厂习语?在这种情况下,我建议您声明Object func();static,并从 的范围内调用它Object,如下所示:

Object o = Object::func();
于 2013-09-11T23:22:45.613 回答
0

试试 Object(const Object &toCopy) { }

于 2013-09-11T23:07:06.767 回答