为什么在添加其他构造函数时会出现此错误?

时间:2013-09-11 23:05:10

标签: c++ constructor compiler-errors

一旦我知道这个主题属于哪个主题,我会很乐意将这个主题的标题更改为更合适的内容。

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

如果我包含那个确切的构造函数,则只会出现此错误:

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 个答案:

答案 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();