NO.10: 在operator=中处理 "自我赋值"

1.确保当对象自我赋值时operator=有良好的行为,其中的技术包括 "来源对象" 和 "目标对象" 的地址,精心周到的语句顺序,以及“ copy and swap ” 技术

2.确定任何函数执行操作一个以上对象时,而其中多个对象是同一个对象时,其行为任然正确

 1 #include <iostream>
 2
 3
 4 //1.0
 5 class CopySwap1_0
 6 {
 7 private:
 8     int *value;
 9 public:
10     CopySwap1_0() : value(new int(200))
11     {}
12
13     ~CopySwap1_0()
14     { delete value; };
15
16     //不符合 "C++异常安全" 1.没有考虑自赋值情况. 2.new抛出异常的话,原数据销毁
17     CopySwap1_0 &operator=(const CopySwap1_0 &rhs)
18     {
19         delete value;
20         value = new int(*rhs.value);
21         return *this;
22
23     }
24
25 };
26
27 //2.0
28 class CopySwap2_0
29 {
30 private:
31     int *value;
32 public:
33     CopySwap2_0() : value(new int(200))
34     {}
35
36     ~CopySwap2_0()
37     { delete value; };
38
39     //保证异常安全,和自赋值情况,但执行效率可以提高
40     CopySwap2_0 &operator=(const CopySwap2_0 &rhs)
41     {
42         if (this == &rhs) return *this;
43
44         int *temp = value;
45         value = new int(*rhs.value);
46         delete temp;
47         return *this;
48     }
49
50 };
51
52
53 //3.0
54 class CopySwap3_0
55 {
56 private:
57     int *value;
58 public:
59     CopySwap3_0() : value(new int(200))
60     {}
61
62     ~CopySwap3_0()
63     { delete value; };
64
65 //    CopySwap3_0 &operator=(const CopySwap3_0 &rhs)
66 //    {
67 //        CopySwap3_0 lhs(rhs);
68 //        std::swap(*this, lhs);
69 //        return *this;
70 //
71 //    }
72
73
74     //copy and swap 方式提高执行效率,放弃自赋值检查(因为自赋值出现几率很小,没必要浪费判断效率)
75     //将 "copying执行" 移至函数参数构造阶段,虽然可读性低,但令编译器有时产生更搞笑的代码
76     CopySwap3_0 &operator=(CopySwap3_0 rhs)
77     {
78         std::swap(*this, rhs);
79         return *this;
80
81     }
82
83 };
84
85
86 int main(int argc, char **argv)
87 {
88     return 0;
89 }
时间: 2024-12-24 09:54:42

NO.10: 在operator=中处理 "自我赋值"的相关文章

Effective C++_笔记_条款11_在operator=中处理“自我赋值”

(整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 为什么会出现自我赋值呢?不明显的自我赋值,是“别名”带来的结果:所谓“别名”就是“有一个以上的方法指涉对象”.一般而言如果某段代码操作pointers或references而它们被用来“指向多个相同类型的对象”,就需要考虑这些对象是否为同一个.实际上两个对象来自同一个继承体系,它们甚至不需要声明为相同类型就可能造成“别名”.因为一个base class的refe

条款11:在operator = 中处理&quot;自我赋值&quot;

条款11:在operator = 中处理"自我赋值" 1.潜在自我赋值 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 *b

Effective C++ 条款11,12 在operator= 中处理&ldquo;自我赋值&rdquo; || 复制对象时不要忘记每一个成分

1.潜在的自我赋值     a[i] = a[j];     *px = *py; 当两个对象来自同一个继承体系时,他们甚至不需要声明为相同类型就可能造成别名. 现在担心的问题是:假如指向同一个对象,当其中一个对象被删,另一个也被删,这会造成不想要的结果. 该怎么办? 比如:   widget& widget:: operator+ (const widget& rhs) {    delete pd;    pd = new bitmap(*rhs.pb);    return *thi

Effective C++ Item 11 在operator= 中处理“自我赋值”

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:确保当对象自我赋值时operator=有良好行为.其中技术包括比较"来源对象"和"目标对象"的地址.精心周到的语句顺序.以及copy-and-swap. 示例:没有"证同测试" #include <iostream> #include <string> using namespace std; class Bi

用3种方法在 operator= 中处理“自我赋值”

假设你建立一个class 用来保存一个指针指向一块动态分配的位图. 1 class Bitmap {......}; 2 class Widget{ 3 ... 4 private: 5 Bitmap* pb ; 6 }; 1 Widget& Widget::operator= (const Widget& rhs) 2 { 3 delete pb; 4 pb = new Bitmap(*rhs.pb); 5 return *this; 6 } 上面是一份不安全的 operator= 实现

effective c++ Item 11 在operator=中处理自我赋值

1.自我赋值是如何发生的 当一个对象委派给自己的时候,自我赋值就会发生: 1 class Widget { ... };2 3 Widget w;4 5 ...6 7 w = w; // assignment to self. 这看上去是愚蠢的,但这是合法的,所以请放心,客户端是可以这么做的.此外,自身赋值也并不总是很容易的能够被辨别出来.举个例子: 1 a[i] = a[j]; // potential assignment to self 上面的代码在i和j相等的情况下就是自我赋值,同样的,

读书笔记 effective c++ Item 11 在operator=中处理自我赋值

1.自我赋值是如何发生的 当一个对象委派给自己的时候,自我赋值就会发生: 1 class Widget { ... }; 2 3 Widget w; 4 5 ... 6 7 w = w; // assignment to self. 这看上去是愚蠢的,但这是合法的,所以请放心,客户端是可以这么做的.此外,自身赋值也并不总是很容易的能够被辨别出来.举个例子: 1 a[i] = a[j]; // potential assignment to self 上面的代码在i和j相等的情况下就是自我赋值,同

条款11:在operator=中处理“自我赋值”

**如果赋值操作=左右值相等,即自我赋值,传统做法: 证同策略:** 为防止new异常,需要在new之前不删除原先的引用: swap技术的运用: 当传递的是值不是引用时同样可用swap: 注意:

条款11:记得在operator=中处理自赋值的情况。

本来的版本是这样的: 1 Widget & Widget::operator=(Widget rhs) 2 { 3 delete pb;//这里可能直接将rhs的pb删除了 4 pb = new (*rhs.pb); 5 return *this; 6 } 这里的代码完全无法处理自赋值的情况,一般是在operator的真正处理之前加上一个“证同测试”,像下面这样: 1 Widget& Widget::operatpr=(const Widget & rhs) 2 { 3 if(*t