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

      

  • 相关阅读:
    JavaWeb——库存管理系统(1)jsp部分---18.12.13
    Java——多线程---18.11.22
    Java——异常处理---18.11.14
    Java——final代码块是否一定被执行---18.11.08
    暑期的周总结们
    Javaweb——四则运算---18.11.01
    Java——equals方法---18.10.18
    微信小程序记账本进度六
    微信小程序记账本进度七
    微信小程序记账本进度一
  • 原文地址:https://www.cnblogs.com/xinsheng/p/3572668.html
Copyright © 2020-2023  润新知