(原創) 為什麼C++須重新定義Copy Control? (C/C++)

C#、Java都沒有Copy Control,為什麼C++需要有Copy Control呢?

C++是個Hybrid語言,除了built-in type和Class type外,還有個其他語言都沒有的歷史產物:pointer,pointer的用途很多,其中一個用途是因為Dynamic Allocation,而且這種由Dynamic Allocation產生的pointer有幾個特點,第一就是他存的是Memory Address不是Data,所以Copy Constructor和Assignment Operator會有問題,第二就是須delete才會消失,不會隨著object out of scope而消失,有static的味道,所以必須自己在Destructor處理。C#、Java因為沒有pointer,因此不需手動處理Copy Constructor和Assignment Operator,但C#、Java雖有Garbage Collection,但C#仍有Destructor,主要是為了處理非Managed的Resource,如File Handler,Database Connection,但Java已經沒有Destructor了。

回到主題,C++的Copy Contructor和Assignment Operator有什麼問題呢?由Compiler所synthesized的程式,只會將pointer加以複製,很顯然最後指向的結果仍是同一份,這樣就沒有達到Copy的意義了,所以我們得自己重新定義Copy Constructor和Assignment Operator。至於Destructor,因為須手動delete,所以Destructor也必須重新定義。換言之,只要Data Member有用到pointer,也就是動態資料結構時,Copy Constructor、Assignment Operator、Destructor就必須重新定義。

以下範例Demo如何撰寫Copy Control處理單一動態資料和動態陣列。

  1 /* 
  2 (C) OOMusou 2007 http://oomusou.cnblogs.com
  3 
  4 Filename    : CopyControl.cpp
  5 Compiler    : Visual C++ 8.0 / ISO C++
  6 Description : Demo how to use Copy Control with dynamic allocation
  7 Release     : 01/15/2007 1.0
  8 */

  9#include <iostream>
 10
 11using namespace std;
 12
 13class Foo {
 14// Constructor
 15public
 16  Foo(int n = 0) : i(n), pi(new int(n)), pia(new int[n]) { cout << "Constructor" << endl; }
 17
 18public:
 19  // Copy Constructor
 20  Foo (const Foo&);
 21  // Assignment Operator
 22  Foo& operator=(const Foo&);
 23  // Destructor
 24  ~Foo();
 25
 26public:
 27  int getStaticInt();
 28  int getDynamicInt();
 29  int getDynamicArray(int);
 30  void setDynamicArray(intint);
 31
 32private:
 33  int i; // static int
 34  int *pi; // dynamic int
 35  int *pia; // dynamic int array
 36}
;
 37
 38// Synthesized Copy Constructor 
 39/*
 40Foo::Foo(const Foo& foo) {
 41  this->i = foo.i;
 42  this->pi = foo.pi;   // Error!! just copy pointer
 43  this->pia = foo.pia; // Error!! just copy pointer
 44}
 45*/

 46
 47// Correct Copy Constructor
 48Foo::Foo (const Foo& foo) {
 49  this->= foo.i;
 50
 51  this->pi = new int(*foo.pi);
 52
 53  this->pia = new int[foo.i];
 54  for(int n = 0; n != this->i; ++n)
 55    this->pia[n] = foo.pia[n];
 56
 57  cout << "Copy Constructor" << endl;
 58}

 59
 60// Synthesized Assignment Operator
 61/*
 62Foo& Foo::operator=(const Foo& foo) {
 63  this->pstring = foo.pstring; // error!! just copy pointer
 64  this->i = 0;
 65  this->d = 0.0;
 66  return *this; 
 67}
 68*/

 69
 70// Correct Assignment Operator
 71Foo& Foo::operator=(const Foo& foo) {
 72  this->= foo.i;
 73
 74  *this->pi = *foo.pi;
 75
 76  /*while(this->pia < this->pia + foo.i)
 77    *(this->pia++) = *(foo.pia++);*/

 78
 79  for(int n = 0; n != this->i; ++n)
 80    this->pia[n] = foo.pia[n];
 81
 82  cout << "Assign Operator" << endl;
 83
 84  return *this
 85}

 86
 87// Destructor
 88Foo::~Foo() {
 89  // delete dynamic int
 90  delete this->pi; 
 91  // delete dynamic int array
 92  delete [] this->pia;
 93
 94  cout << "Destructor" << endl;
 95}

 96
 97int Foo::getStaticInt() {
 98  return this->i;
 99}

100
101int Foo::getDynamicInt() {
102  return *this->pi;
103}

104  
105int Foo::getDynamicArray(int n) {
106  return this->pia[n];
107}

108
109void Foo::setDynamicArray(int n, int val) {
110  if (n >= 0 && n < this->i) 
111    this->pia[n] = val;
112}

113
114int main() {
115  Foo foo1;
116  cout << foo1.getStaticInt() << endl;
117  cout << foo1.getDynamicInt() << endl;
118
119  Foo foo2(3);
120  cout << foo2.getStaticInt() << endl;
121  cout << foo2.getDynamicInt() << endl;
122
123  for(int n = 0; n != 3++n) 
124    foo2.setDynamicArray(n, n+1);
125
126  cout << foo2.getDynamicArray(0<< endl;
127
128  Foo foo3(foo2);  // foo3's Copy Constructor
129  Foo foo4 = foo2; // Syntax sugar!! foo4's Copy Constructor
130
131  Foo foo5(3);
132  foo5 = foo3;     // foo5's Assignment Operator
133  cout << foo5.getDynamicArray(1<< endl;
134}


執行結果

Constructor
0
0
Constructor
3
3
1
Copy Constructor
Copy Constructor
Constructor
Assign Operator
2
Destructor
Destructor
Destructor
Destructor
Destructor

posted on 2007-01-15 01:19  真 OO无双  阅读(1930)  评论(0编辑  收藏  举报

导航