2

当调用 [abc e = a+b] 时,不会调用复制构造函数。

class abc{
        int i;
        public:
        abc()
            {
            i = 10;
            cout<<"constructor"<<endl; 
        }
        abc(const abc &a)
        {   
            cout<<"copy constructor"<<endl;
            i = a.i; 
        }
        abc operator=(const abc &a)
        {
            cout<<"operator="<<endl;
            abc temp;
            temp.i = a.i;
            return temp;
        }
        abc operator+(abc& a)
        {   
            cout <<"Operator+ called"<<endl;
            abc temp;
            temp.i = i+a.i;
            return temp ;
        }
    };

    int main()
    {
        abc a,b;
        cout <<"----------------------------------------------"<<endl;
        a = b;
        cout <<"----------------------------------------------"<<endl;
        abc c = a;
        cout <<"-----------------------------------------------"<<endl;
        abc d(a);
        cout <<"-------------------------------------------"<<endl;
        **abc e = a+b;** 
    }

但是,如果将重载运算符方法替换为以下返回对 abc 类对象的引用的方法,则会调用复制构造函数。

abc& operator=(const abc &a)
    {
        cout<<"operator="<<endl;
        i = a.i;
        return *this;
    }
    abc& operator+(const abc& a)
    {   
        cout <<"Operator+ called"<<endl;
        i = i+a.i;
        return *this ;
    }

有人可以解释为什么会这样吗?

4

3 回答 3

1

这是由于返回值优化而发生的。

如果您的构造函数返回引用,则不会进行昂贵的内存复制操作,因此它可以按您预期的方式工作,因为在这种情况下没有进行任何优化。如果它返回一个值,优化就会启动,它会以某种出乎意料的方式工作(对你来说),但标准允许这样做。

于 2012-08-13T05:35:45.747 回答
0

它是标准明确允许的优化。

在 n3376
12.8 第 31 段中:

当满足某些条件时,允许实现省略类对象的复制/移动构造,即使为复制/移动操作选择的构造函数和/或对象的析构函数具有副作用。

这种优化可以通过RVO(这种情况)和在某些条件下NRVO来实现。

于 2012-08-13T05:32:34.617 回答
0

您可以禁用编译器上的优化选项。请检查编译代码时使用的优​​化标志。

于 2012-08-23T14:16:37.097 回答