• Effective C++ Item 10,11 Have assignment operators return a reference to *this Handle assignment to self in operator =


    If you want to concatenate assignment like this

    int x, y, z;
    x = y = z = 15;
    

    The convention is to make the assignment operators return a reference to *this.

    11 Handle assignmnet to self in operator = 

    You can easily assign an object to itself without knowing it

    // Example 1
    Foo *px, *py;
    px = py;
    
    //Example 2
    a[i] = a[i];
    

    It is dangerous to assign an object to self if your class doesn't handle this kind of opeator appropriately. Let's consider an example here:

    class Bitmap{...};
    
    class Widget {
    	...
    private:
    	Bitmap *m_pb;
    };
    
    Widget& Widget::operator=(const Widget& rhs) {
    	delete m_pb;
    	m_pb = new Widget(rhs);
    	return *this;
    }
    

    You will be dead if you assign an object to itself, beacause you will end up holding a pointer to a deleted object!

    One way but not the best way to deal with self assignment is to write code to explicitly deal with this situation:

    Widget& Widget::operator=(const Widget& rhs) {
    	if(this == &rhs) {
    		return *this;
    	}
    	
    	delete m_pb;
    	m_pb = new Bitmap(*rhs).m_ph;
    	return *this;
    }
    

    This is not the best way because above this operator is not exception-safe. What does that mean? Imagine what if an exception is thrown when

    ph = new Bitmap(*rhs.m_ph)
    

    is been executed(for example, not enough memory), then the object will hold a pointer to a deleted object.

    Luckily, making operator= safe renders it self-assignmnet-sage, too. So, the best way to accomplish that is:

    Widget& Widget::operator=(const Widget& rhs) {
    	Bitmap* tmp = m_pb;
    	pb = new Bitmap(*rhs.m_pb);
    	delete tmp;
    	return *this;
    }
    

    Now if "new Bitmap" throw an exception, pb remains unchanged. Even without the identity test, this code handle assignment to self, because we make a copy of the original bitmap, point to the copy we made, and then delete the original Bitmap.

    A more straightforward way to do so is to use exception-safe function swap

    Widget& Widget::operator=(const Widget& ths) {
    	Widget temp(ths);
    	swap(temp);
    	return *this;
    }
    

      

  • 相关阅读:
    linux下的第一个C程序及其编译方法
    使用open_read_write等底层函数来赋值一个文件
    C++中预定义的宏
    altibase MDB的创建sequence的举例
    C中的时间函数的用法
    联系表单 1
    《jQuery基础教程》读书笔记
    《jQuery基础教程》读书笔记
    《jQuery基础教程》读书笔记
    『原创·翻译』如何阅读论文
  • 原文地址:https://www.cnblogs.com/xinsheng/p/3572668.html
Copyright © 2020-2023  润新知