為什麼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
 11 using   namespace  std;
 12
 13 class  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
 48 Foo::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
 71 Foo &  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
 88 Foo:: ~ 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
 97 int  Foo::getStaticInt()  {
 98  return this->i;
 99}

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

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

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

113
114 int  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

你可能感兴趣的:(c/c++)