赋值运算符的重载,有不同的方法,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 阅读(238)
评论(0) 编辑 收藏 引用