關(guān)于含有成員指針的類的復(fù)制控制
一個(gè)類中如果含有了指針成員,在不加任何措施的時(shí)候,復(fù)制類對(duì)象是做的位復(fù)制操作,即是所謂的淺拷貝,兩個(gè)對(duì)象的指針式一樣的值,指向同一塊內(nèi)存區(qū)。
這種情況下,當(dāng)一個(gè)對(duì)象刪除其成員指針指向的內(nèi)存區(qū)后,另一個(gè)對(duì)象的指針成員指向的內(nèi)存區(qū)也就被釋放了。
如果第一個(gè)對(duì)象析構(gòu)時(shí)刪除了這個(gè)內(nèi)存區(qū),那么在第二對(duì)象析構(gòu)時(shí)造成同一塊內(nèi)存多次被釋放,程序崩潰。
解決這個(gè)問題有常規(guī)上有兩種方法
一是,進(jìn)行深拷貝,在拷貝構(gòu)造函數(shù)和復(fù)制運(yùn)算符中進(jìn)行相應(yīng)的內(nèi)存分配和復(fù)制工作。析構(gòu)的時(shí)候只是各自析構(gòu)各自的。
二是,采用引用計(jì)數(shù)手段,在拷貝構(gòu)造函數(shù)和復(fù)制運(yùn)算符中對(duì)引用計(jì)數(shù)進(jìn)行分析,多個(gè)復(fù)制對(duì)象的指針成員只指向同一個(gè)內(nèi)存區(qū),在最后一個(gè)對(duì)象析構(gòu)的時(shí)候才最終將這個(gè)內(nèi)存區(qū)釋放掉。
引用計(jì)數(shù)的好處是,可以節(jié)省內(nèi)存分配、拷貝、內(nèi)存釋放所帶來的效率消耗,以及節(jié)省內(nèi)存。
http://www.shnenglu.com/jake1036/archive/2011/05/17/146594.html
淺拷貝
1 #include <iostream>
2 #include <cstring>
3 using namespace std;
4
5 class str
6 {
7 private:
8 char* s_;
9 public:
10 str(const char* s = "")
11 {
12 s_ = new char[strlen(s) + 1];
13 if (s_ != 0)
14 {
15 strcpy(s_, s);
16 }
17 }
18 ~str()
19 {
20 delete [] s_;
21 }
22 char* s() const
23 {
24 return s_;
25 }
26 };
27
28 ostream& operator << (ostream& out, const str& s)
29 {
30 out << s.s() << endl;
31 return out;
32 }
33
34 int main()
35 {
36 str s1 = "123";
37 str s2(s1);
38 cout << s1 << endl;
39 cout << s2 << endl;
40 }
深拷貝
1 #include <iostream>
2 #include <cstring>
3 using namespace std;
4
5 class str
6 {
7 private:
8 char* s_;
9 public:
10 str(const char* s = "")
11 {
12 s_ = new char[strlen(s) + 1];
13 if (s_ != 0)
14 {
15 strcpy(s_, s);
16 }
17 }
18 str(const str& s)
19 {
20 s_ = new char[strlen(s.s_) + 1];
21 if (s_ != 0)
22 {
23 strcpy(s_, s.s_);
24 }
25 }
26 str& operator = (const str& s)
27 {
28 if (this != &s)
29 {
30 delete [] s_;
31 s_ = new char[strlen(s.s_) + 1];
32 if (s_ != 0)
33 {
34 strcpy(s_, s.s_);
35 }
36 }
37 return *this;
38 }
39 ~str()
40 {
41 delete [] s_;
42 }
43 char* sr() const
44 {
45 return s_;
46 }
47 };
48
49 ostream& operator << (ostream& out, const str& s)
50 {
51 out << s.sr() << endl;
52 return out;
53 }
54
55 int main()
56 {
57 str s1 = "123";
58 str s2(s1);
59 cout << s1 << endl;
60 cout << s2 << endl;
61 }
引用計(jì)數(shù)
引用計(jì)數(shù)的實(shí)現(xiàn)是通過在類對(duì)象中增加一個(gè)指向 int 型的指針,這個(gè)指針指向的那個(gè) int 即是計(jì)數(shù),記錄指針指向的那塊內(nèi)存被幾個(gè)對(duì)象共用著。
采用引用計(jì)數(shù),在構(gòu)造函數(shù)、析構(gòu)函數(shù)、拷貝構(gòu)造函數(shù)、復(fù)制運(yùn)算符中,都要對(duì)這個(gè)指向 int 的指針進(jìn)行操作,并且需要判斷指針指針指向 int 的變化情況,當(dāng)為 0 時(shí),則要釋放掉指針指向的內(nèi)存。
1 #include <iostream>
2 #include <cstring>
3 using namespace std;
4
5 class str
6 {
7 private:
8 char* s_;
9 int* pcount_;
10 public:
11 str(const char* s = "")
12 {
13 s_ = new char[strlen(s) + 1];
14 if (s_ != 0)
15 {
16 strcpy(s_, s);
17 pcount_ = new int;
18 if (pcount_ != 0)
19 {
20 *pcount_ = 1;
21 }
22 }
23 }
24 str(const str& s)
25 {
26 s_ = s.s_;
27 pcount_ = s.pcount_;
28 ++(*pcount_);
29 }
30 str& operator = (const str& s)
31 {
32 if (this != &s)
33 {
34 --(*pcount_);
35 if (*pcount_ == 0)
36 {
37 if (s_ != 0)
38 {
39 delete [] s_;
40 s_ = 0;
41 }
42 delete pcount_;
43 pcount_ = 0;
44 }
45 s_ = s.s_;
46 pcount_ = s.pcount_;
47 ++(*pcount_);
48 }
49 return *this;
50 }
51 ~str()
52 {
53 --(*pcount_);
54 if (*pcount_ == 0)
55 {
56 // cout << "test" << endl;
57 if (s_ != 0)
58 {
59 delete [] s_;
60 s_ = 0;
61 }
62 delete pcount_;
63 pcount_ = 0;
64 }
65 }
66 char* sr() const
67 {
68 return s_;
69 }
70 };
71
72 ostream& operator << (ostream& out, const str& s)
73 {
74 out << s.sr() << endl;
75 return out;
76 }
77
78 int main()
79 {
80 str s1 = "123";
81 str s2(s1);
82 cout << s1 << endl;
83 cout << s2 << endl;
84 }
85
posted on 2011-07-22 17:20
unixfy 閱讀(265)
評(píng)論(0) 編輯 收藏 引用