賦值運算符的重載,有不同的方法,Effective C++ 中有一個條款對此介紹。
1 #include <iostream>
2 using namespace std;
3
4 class MyString
5 {
6 private:
7 unsigned len;
8 char* data;
9 public:
10 MyString(const char* s = "");
11 MyString(const MyString& s);
12 MyString& operator = (const MyString& s);
13 ~MyString();
14 };
15
16 MyString::MyString(const char* s)
17 {
18 len = strlen(s);
19 data = new char[len + 1];
20 if (data != 0)
21 {
22 strcpy(data, s);
23 }
24 }
25
26 MyString::MyString(const MyString& s)
27 {
28 len = s.len;
29 data = new char[len + 1];
30 if (data != 0)
31 {
32 strcpy(data, s.data);
33 }
34 }
35
36 MyString& MyString:: operator = (const MyString& s)
37 {
38 // 第一種方法,需要檢測自賦值,因為如果不檢測,則會造成當自賦值時,就直接將該對象的 data delete 了,也就是 s.data 被 delete 了。這時 s.data 是個懸置指針,所致內存極可能無效
39 //
40 //if (this != &s)
41 //{
42 // delete [] data;
43 // len = s.len;
44 // data = new char[len + 1];
45 // if (data != 0)
46 // {
47 // strcpy(data, s.data);
48 // }
49 //}
50 //return *this;
51
52 // 另一種方法, 不需要檢測自賦值
53 // 這種方式需要做一個備份,自賦值情況下,temp 保持了另一份備份,即便 delete 了 data 還是留有一份
54 // 非自賦值的情況下,對 s.data 所指的內容有了一個備份,然后 delete data,將 temp 賦予 data,這樣有了兩份 s.data,到達賦值的目的
55 len = s.len;
56 char* temp = new char[len + 1];
57 if (temp != 0)
58 {
59 strcpy(temp, s.data);
60 }
61 delete [] data;
62 data = temp;
63 return *this;
64
65 // 兩種方法的代價分析
66 // 第一種方法,需要每次都要檢測是不是自賦值了,對于自賦值的情況,雖然檢測了,但是避免了備份,有利于自賦值的情況。但是對于非自賦值的情況,都需要額外的檢測,這種檢測是浪費的
67 // 第二種方法,不管是自賦值還是非自賦值都需要備份,這種方法對于自賦值的情況,較第一種方法代價高些,但是對于非自賦值的情況它不需要檢測,也是做一個 copy 所以非自賦值的情況效率由于第一種方法
68 // 也就是說第一種方法對于自賦值的情況好,第二種方法對于非自賦值的情況好。一般情況下,自賦值的情況并不經常出現,所以第一種檢測自賦值的操作很多情況下是多余的,所以相對第一種方法,第二種方法更好些。
69 }
70
71 MyString::~MyString()
72 {
73 len = 0;
74 delete [] data;
75 }
76
77 int main()
78 {
79 MyString a("C++ Programming"), c("Hello");
80 MyString b(a);
81 c = b;
82 cout << ". . ." << endl;
83 return 0;
84 }
posted on 2011-06-16 10:56
unixfy 閱讀(242)
評論(0) 編輯 收藏 引用