【问题标题】:assignment operator return a reference to *this in C++赋值运算符在 C++ 中返回对 *this 的引用
【发布时间】:2011-08-05 21:40:54
【问题描述】:

我从“Effective c++”中读到了这个,这是 Col.10。 它说这是让赋值运算符返回对 *this 的引用的好方法。 我写了一个代码 sn-p 来测试这个想法。我在这里覆盖了赋值运算符。并对其进行了测试。一切顺利。 但是当我删除该运算符覆盖时,一切都是一样的。这意味着,链接分配仍然可以正常工作。那么,我错过了什么?这是为什么?需要你们解释一下,谢谢。

#include <iostream>

using namespace std;

class Widget{
public:

    Widget& operator=(int rhs)
    {
        return *this;
    }
    int value;

};

int main()
{
    Widget mywidget;
    mywidget.value = 1;
    Widget mywidget2;
    mywidget2.value = 2;
    Widget mywidget3 ;
    mywidget3.value = 3;
    mywidget = mywidget2 = mywidget3;
    cout << mywidget.value<<endl;
    cout << mywidget2.value<<endl;
    cout << mywidget3.value<<endl;

}

【问题讨论】:

    标签: c++


    【解决方案1】:

    这个问题涉及两个不同的概念,您是否应该定义operator=,以及在这样做时是否应该返回对该对象的引用。

    你应该考虑三者的规则:如果你定义了 copy constructorassignment operatordestructor 之一,你应该定义这三个其中。围绕该规则的基本原理是,如果您需要提供析构函数,则意味着您正在管理资源,并且在这样做时,默认的 复制构造函数赋值运算符 em> 不会削减它。例如,如果您通过原始指针持有内存,那么您需要在析构函数中释放内存。如果您不提供复制构造函数赋值运算符,那么指针将被复制,两个不同的对象将尝试释放指针持有的内存。

    虽然指针是最常见的例子,但这也适用于任何资源。例外情况是您禁用复制构造和赋值的类——但你又以某种方式定义它们被禁用

    关于问题的第二部分,或者您是否应该返回对该对象的引用,您应该这样做。与所有其他运算符重载一样,原因是模仿基本类型的现有运算符通常是一个很好的建议。这有时由引号给出:重载运算符时,像ints 那样做

    【讨论】:

      【解决方案2】:

      如果完全删除operator= 方法,编译器将创建一个默认的operator=,它实现浅拷贝1 并返回对*this 的引用。

      顺便说一句,当你写的时候

      mywidget = mywidget2 = mywidget3;
      

      您实际上是在调用此默认 operator=,因为您的重载运算符旨在与右侧的 ints 一起使用。

      如果你返回一个值、const 引用(=>你会得到编译错误)或对不同于 *this 的引用(违反直觉的东西),则链式赋值将停止工作将开始发生)。

      部分相关:copy and swap idiom,即编写赋值运算符的完美方式。如果您需要写operator=

      ,强烈建议阅读
      1. 默认operator= 的执行就像在左手操作数的每个成员和右手操作数的每个成员之间存在赋值一样。这意味着对于原始类型,它将是一个“残酷”的按位复制,在 90% 的情况下,这对于指向拥有资源的指针是不合适的。

      【讨论】:

      • 哦,我明白了。那么,我应该总是在我的代码中这样做吗?还是让编译器来处理?
      • 如果你的班级需要,你需要实现operator=,也就是说,如果默认的按位复制不适合它。这通常发生在您拥有指向您的类所拥有资源的内存/句柄的原始指针时;一个好的经验法则是,如果您需要一个析构函数来释放一些资源,您可能需要一个operator= 以避免在不同实​​例之间不必要地共享这些资源、双重释放和资源泄漏。
      • 不是真正的按位复制...对于没有自己的operator= 的成员,它将执行按位复制,但对于实现它的成员(想想std::string)现有的将使用operator= 的成员。
      • “指向自有资源的指针”是什么情况?可以举个简单的例子吗?
      • @Don Lun:假设您的类在构造时分配了一个动态数组,将其存储在指针成员中并在析构函数中释放它;一切似乎工作正常,但如果你将此类的一个实例分配给另一个具有默认 operator= 的实例,你将得到 (1) 内存泄漏,因为目标实例的数组指针将被覆盖而没有任何机会释放内存指向 (2) 不需要的资源共享,因为现在两个实例都使用相同的内部数组,以及 (3) 双重释放,因为两个实例在销毁时都会尝试delete[] 相同的数组。
      【解决方案3】:

      Widget&amp; operator=(int rhs)

      这允许您将 int 分配给 Widget - 例如mywidget = 3;

      创建一个Widget&amp; operator=(Widget const &amp; rhs) - 它会在您的mywidget = mywidget2 = mywidget3; 行中调用。

      您不需要 operator=(Widget const &amp; rhs) - 默认值应该可以。

      另外,添加例如cout &lt;&lt; "operator=(int rhs)\n"; 给您的自定义运算符 - 然后您会看到它在您的代码中根本没有被调用。

      【讨论】:

        猜你喜欢
        • 2011-03-15
        • 1970-01-01
        • 2015-05-31
        • 1970-01-01
        • 2013-05-26
        • 2021-02-20
        • 2011-12-12
        • 2012-02-22
        相关资源
        最近更新 更多