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

defining explicit overloaded constructor issue

本文关键字:构造函数 问题 重载 定义      更新时间:2023-10-16

我有以下类,其中一些操作符是重载的:

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
       }
}

现在,编译器给出'没有匹配的函数调用…错误(在上面的代码中指定),尽管我显式地重载了赋值操作符。我错在哪里?

当按值返回对象时,复制构造函数被隐式地调用。如果你说它不允许被隐式调用,你会得到一个错误。

你不应该使用explicit作为你的默认、复制或移动构造函数。或用于接受多个参数的构造函数。

从技术上讲,当从方法返回对象时,在方法调用外部接收的对象实际上是在方法内部声明的对象的副本。因此编译器必须有一种允许的方式将内容从方法内对象"转移"到方法结果。由于不再需要方法内实例,移动是最好的方法(是的,您需要添加移动构造函数):

CLASS1(CLASS1&& obj);

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

在现实生活中,上述复制/移动很可能会被RVO/NRVO优化掉。