int i = 5; int *x = &i; int *y = &i; *x = *y;
class Base{};
class Derived: public Base {};
void DoSomeThing(const Base& base, const Derived &derived)
{
base = derived;
}
Derived d;
Base *base = &d;
DoSomeThing(*base, d); //base和d指向同一个对象,调用会自我赋值 一般而言如果某段代码操作pointers或references而它们被用来“指向多个相同类型的对象”,就需要考虑这些对象是否为同一个。实际上两个对象只要来自同一个继承体系,它们甚至不需要声明为相同类型就可能造成“别名”,因为一个base
class的reference或pointer可以指向一个derived class对象。class Bitmap
{
public:
Bitmap(const std::string &option) {this->m_option = option;}
Bitmap(const Bitmap &rhs)
{
this->m_option = rhs.m_option;
}
std::string GetOption() const { return this->m_option;}
private:
std::string m_option;
};
class Widget
{
public:
Widget()
{
this->m_b = new Bitmap("");
this->m_count = 0;
}
~Widget()
{
if (m_b != NULL)
delete m_b;
m_b = NULL;
}
Widget(const Bitmap &bmap, const int count)
{
this->m_b = new Bitmap(bmap.GetOption());
this->m_count = count;
}
Widget(const Widget &rhs)
{
this->m_b = new Bitmap(*rhs.m_b);
this->m_count = rhs.m_count;
}
Widget& operator = (const Widget &rhs) //错误的赋值函数
{
delete this->m_b;
this->m_b = new Bitmap(*rhs.m_b);
this->m_count = rhs.m_count;
return *this;
}
private:
Bitmap *m_b;
int m_count;
}; Bitmap bmap("fenggao");
Widget wget(bmap, 3);
wget = wget; //调用自我赋值,该对象意外释放 防止出现这种情况,可以通过“证同测试”,修改赋值函数 Widget& operator = (const Widget &rhs)
{
if (this == &rhs)
return *this;
delete this->m_b;
this->m_b = new Bitmap(*rhs.m_b);
this->m_count = rhs.m_count;
return *this;
} 大多数这种情况已经可以达到“自我赋值安全性”目的,但是分析程序,如果在new Bitmap(*rhs.m_b)中抛出异常(系统没有可分配内存或者Bitmap拷贝构造函数抛出异常),最后Widget的m_b则指向一块被删除的内存,程序出现了不可意料的行为,即“异常安全性”问题出现了。 Widget& operator = (const Widget &rhs)
{
Bitmap *bt = this->m_b; //临时存取旧的空间
this->m_b = new Bitmap(*rhs.m_b); //分配新的空间并赋值,如果分配内存失败则还是保留旧的内存
this->m_count = rhs.m_count;
delete *bt; //释放旧的空间
return *this;
} friend void Swap(Widget &lrs, Widget &rhs)
{
std::swap(lrs.m_b, rhs.m_b);
std::swap(lrs.m_count, rhs.m_count);
}
Widget& operator = (const Widget &rhs)
{
Widget temp(rhs);
Swap(*this, temp);
return *this;
}
Widget& operator = (Widget rhs)
{
Swap(*this, rhs);
return *this;
}条款11:在operator = 中处理"自我赋值",布布扣,bubuko.com
原文:http://blog.csdn.net/hualicuan/article/details/27073681