当我从类成员函数返回*this时,为什么要调用我的复制构造函数?

Eri*_*son 3 c++

我知道我的副本构造函数和重载运算符在这种情况下是相当随意的,但我找人验证我是否正确使用它们,以及正确使用*.

另外,有人可以告诉我为什么每次从任何重载运算符返回*this或Rectangle类型的对象时都会调用复制构造函数吗?

class Rectangle
{
    private:
        int length;
        int width;
        static int counter;
    public:
        Rectangle(int len = 0, int w = 0)
        {
            length = len;
            width = w;
            counter++;
        }
        ~Rectangle()
            { counter--; }
        static int getCounter()
            { return counter; }

        Rectangle(const Rectangle &);
        Rectangle operator+ (const Rectangle &);
        Rectangle operator= (const Rectangle &);
};

int Rectangle::counter = 0;

Rectangle::Rectangle(const Rectangle &right) : Rectangle()
{
    width = right.width;
    length = right.length;
}

Rectangle Rectangle::operator+ (const Rectangle &right)
{
    width += right.width;
    length += right.length;
    return *this;
}

Rectangle Rectangle::operator= (const Rectangle &right)
{
    width = right.width;
    length = right.length;
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

kfs*_*one 5

其他人评论了如何通过值返回调用您的复制构造函数,所以我只是回答问题的第一部分:

如果我正确地使用它们,以及正确使用*这个.

您的运算符重载错误:

Rectangle Rectangle::operator+ (const Rectangle &right)
{
    width += right.width;
    length += right.length;
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

这会修改*this然后返回它的副本.这不是你所期望的:

int b = 1, c = 2;
int a = b + c;
Run Code Online (Sandbox Code Playgroud)

在上文中,b和c未经修改.生成一个新值并存储在a中.

Rectangle Rectangle::operator+ (const Rectangle &right) const
{
    Rectangle newValue(*this);  // copy ctor temporary
    newValue.length += right.length;
    newValue.width += right.width;
    return newValue;
}
Run Code Online (Sandbox Code Playgroud)

或者如果你已经超负荷,operator+=你可以用它来写:

Rectangle Rectangle::operator+ (const Rectangle &right) const
{
    Rectangle newValue(*this);  // copy ctor temporary
    newValue += right;
    return newValue;
}
Run Code Online (Sandbox Code Playgroud)

编译器通常能够执行返回值优化并忽略此代码本来会产生的副本之一.

其次:

Rectangle Rectangle::operator= (const Rectangle &right)
{
    width = right.width;
    length = right.length;
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

正如您所了解的那样,按值返回会返回一个副本.operator =应该返回对当前对象的引用:

Rectangle& Rectangle::operator= (const Rectangle& right)
{
    width = right.width;
    length = right.length;
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

考虑

a = b = c;
Run Code Online (Sandbox Code Playgroud)

这执行

a.operator=(b.operator=(c));
Run Code Online (Sandbox Code Playgroud)

返回引用将为我们保存一个副本,生成参数到a.operator =.

我将完成这个使用*this的建议:

当您返回引用时,*这表示"返回对此类型的具体实例的引用".当你返回一个值而你说"*this"时,你会说"返回这个看起来像这个类的rvalue(可修改)实例",它会调用一个副本.