定义显式重载构造函数问题

时间:2016-10-31 05:11:45

标签: c++ operator-overloading

我有以下课程,其中一些操作符被重载:

class CLASS1
{
       CLASS1();
       CLASS1(const CLASS1 &obj);

   CLASS1 operator +(const CLASS1 &obj) {
       CLASS1 srcObj;
       // doing add stuff here
           return srcObj;
       }

   void func()
   {
   CLASS1 boj = // some method which returns CLASS1 obj.
   }


   CLASS1& operator =(const CLASS1 &obj) {
       // copy properties
       }
}

好的,这很好用。但过了一段时间后,我决定让我的课明确,以避免隐式转换。因此,我已经这样做了:

class CLASS1
{
       explicit CLASS1();
       explicit CLASS1(const CLASS1 &obj);

   CLASS1 operator +(const CLASS1 &obj) {
       CLASS1 srcObj;
       // doing add stuff here
           return srcObj;          // compiler gives non-matching errors
   }

   void func() {
       CLASS1 boj = somemethods(); // compiler gives non-matching errors
   }

   CLASS1& operator =(const CLASS1 &obj) {
       // copy properties
       }
}

现在,编译器给出了“没有匹配函数来调用...”错误(在上面的代码中指定),尽管我明确地重载了​​赋值运算符。我的错误在哪里?

2 个答案:

答案 0 :(得分:2)

按值返回对象时,复制构造函数将隐式调用 。如果你说不允许隐式调用,你会收到错误。

您不应将explicit用于默认,复制或移动构造函数。或者对于构造函数采取多个参数。仅适用于采用单个参数的构造函数(具有注明的例外)。

答案 1 :(得分:1)

从技术上讲,从方法返回对象时,在方法调用之外接收的对象实际上是在方法内声明的对象的副本。所以编译器必须有一个允许的方式来传输内容"从in-method对象到方法结果。由于不再需要in-method实例,因此移动是最佳方法(是的,您需要添加移动构造函数):

CLASS1(CLASS1&& obj);

这将允许您禁止隐式转换,同时保持具有临时对象的能力。

在现实生活中,可能会被RVO / NRVO优化出来的副本/移动。