Mixture

身未动,心已远

导航

effective c++ 11: Handle assignment to self in operator =

比如有这样一个class:

class A {};

class B {
    ...
private:
    A* a;
};

在写class B的赋值函数的时候,假如写成下面这样:

B& B::operator=(const B& rhs) {
    delete a;
    a = new A(*rhs.a);
    return *this;
}

假如是自我赋值,那上面这个代码显然就不对了,*this和rhs是一个对象,所以如果都delete a 了下面还怎么new A(*rhs.a)呢。

可以通过identity test检查是否是自我赋值:

if(this==&rhs) return *this

 

在上面那个自我赋值会产生问题的代码里,还有一处安全隐患(不具备“异常安全性”),就是即使不是自我赋值,假如在new的时候出现了异常,那么A的指针a还是指向了不安全的区域。

可以通过下面的方法解决这个问题:

B& B::operator=(const B& rhs) {
    A* pOrig = a;
    a = new A(*rhs.a);//a指向原来a的一个副本
    delete pOrig;
    return *this;
}

这样即使在new的时候出现了异常,a还是指向原来的a。

 

还有个方案是copy and swap

class B {
..
void swap(B& rhs);
..
};

B& B::operator=(const B& rhs) {
    B tmp(rhs); //rhs的副本
    swap(tmp);
    return *this;
}

 

posted on 2014-04-07 00:08  parapax  阅读(259)  评论(0编辑  收藏  举报