zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

  • 相关阅读:
    机器人平台框架Yarp
    Git常用使用技巧
    Qt 5.x 开发技巧
    ROS (Robot Operating System) 相关资料与文档
    图形图像技术在手游中的潜在应用
    【Jmeter】Jmeter参数化的几种方式
    【Jmeter】调试取样器(Debug Sampler)进行调试
    【jmeter】实现接口关联的两种方式:正则表达式提取器和json提取器
    【Jmeter】Jmeter安装配置教程
    【Jmeter】第一个接口测试案例
  • 原文地址:https://www.cnblogs.com/xinsheng/p/3572668.html
Copyright © 2011-2022 走看看