該程序演示了vector中的元素為指針的時候的對對象的操作。
1 /* 2 功能說明: 3 元素為指針的vector的使用說明 4 實現方式: 5 使用this成員來顯示各個對象的地址。 6 限制條件或者存在的問題: 7 無 8 */ 9 #include <iostream> 10 #include <string> 11 #include <vector> 12 13 using namespace std; 14 15 class CData 16 { 17 public: 18 CData() 19 { 20 sequence = 0; 21 this->remark = "default string"; 22 23 cout << "CData()\t" << toString() <<"\t"<< this << endl; 24 } 25 26 CData(int i,string &s) 27 { 28 this->sequence = i; 29 this->remark = s; 30 31 cout << "CData(int i,string &s)\t" << toString() << "\t" << this << endl; 32 } 33 34 void setSequence(const int i) 35 { 36 this->sequence = i; 37 } 38 39 void setRemark(const string &s) 40 { 41 this->remark = s; 42 } 43 44 string toString() const 45 { 46 char tmp[2048] = { 0 }; 47 sprintf(tmp, "[sequence:%d | remark:%s]", this->sequence, this->remark.c_str()); 48 49 //此處應該有內存復制操作,所以不用擔心返回后tmp數組所指向的內存被修改或者不存在的情況。 50 return tmp; 51 } 52 53 ~CData() 54 { 55 cout << "~CData()\t" << this << endl; 56 } 57 protected: 58 private: 59 int sequence; 60 string remark; 61 }; 62 63 int main(int argc, char **argv) 64 { 65 cout << "process begin at " << (void*)&main << endl; 66 67 string str = "baby test"; 68 // 查看保存在系統的棧中的對象的地址。 69 cout << "==========test class object in stack" << endl; 70 CData data1; 71 cout << "address of object in stack:" << &data1 << "\tdefalut object elements:" << data1.toString() << endl; 72 data1.setSequence(11); 73 data1.setRemark(str); 74 cout << "address of object in stack:" << &data1 << "\tafter set object elements:" << data1.toString() << endl; 75 76 // 查看保存在系統的堆中的對象的地址。這種對象需要手工刪除,否則會造成內存泄露 77 cout << "\n==========test class object in heap" << endl; 78 CData *p_data12 = new CData(12, str); // 帶有參數的構造函數的第二個參數為一個地址,所以,此處的調用必須為一個對象。不能是一個字符數組。 79 cout << "address of pointer of class object in stack:" << &p_data12 << "\taddress of class object in heap:" << p_data12 << "\tobject in heap:" << p_data12->toString() << endl; 80 81 CData *p_data13 = new CData(13, str); 82 cout << "address of pointer of class object in stack:" << &p_data13 << "\taddress of class object in heap:" << p_data13 << "\tobject in heap:" << p_data13->toString() << endl; 83 84 cout << "\n==========vector test. object in heap" << endl; 85 vector<CData*> vec_data; 86 vec_data.push_back(p_data12); 87 vec_data.push_back(p_data13); 88 vec_data.push_back(p_data12); 89 vec_data.push_back(p_data13); 90 // 上述操作完成之后,堆中有2個對象,但是,這兩個對象分別有3個指針來指向他。一個是原始的創建對象的時候的。另外兩個是上面的push_back所復制的。 91 cout << "show vector's msg" << endl; 92 for (int i = 0; i < vec_data.size(); i++) 93 { 94 // 查看vector元素的地址,說明,vector中的元素的位置是連續的。 95 cout << "address of element in vector:" << &(vec_data[i]) << endl; 96 CData *pTmp = vec_data[i]; 97 cout << "object address in heap:" << pTmp << "\tobject msg in heap:" << (pTmp)->toString() << endl; 98 } 99 100 vec_data.clear(); 101 // 清理掉vector中的元素。也僅是清理掉vector中的指向對象的指針,並沒有清理掉這些指針所指向的對象。另外,其原始的指向對象的指針還是存在的。 102 cout << "\n==========check objects in heap after clear vector" << endl; 103 cout << "address of class object in heap:" << p_data12 << "\tobject in heap:" << p_data12->toString() << endl; 104 cout << "address of class object in heap:" << p_data13 << "\tobject in heap:" << p_data13->toString() << endl; 105 106 cout << "\n==========delete object in heap using vector iterator" << endl; 107 // 再將兩個對象的指針復制到vector中。 108 vec_data.push_back(p_data12); 109 vec_data.push_back(p_data13); 110 for (vector<CData*>::iterator itr = vec_data.begin(); itr != vec_data.end(); itr++) 111 { 112 // 通過迭代器來刪除每個指針指向的對象。如果vector中的多個元素指向了同一個對象(上面的情形),此處的程序會異常退出。 113 cout <<"delete object:" << *itr << endl; 114 delete *itr; 115 *itr = 0; 116 } 117 118 // 清理vector元素中的指針所指向的對象。並不意味着去清理了vector本身,所以,其長度還是原來的數值。 119 cout << "vector length is " << vec_data.size() << endl; 120 cout << "\n==========check objects in heap using vector after delete objects" << endl; 121 for (vector<CData*>::iterator itr = vec_data.begin(); itr != vec_data.end(); itr++) 122 { 123 // vecotr中的指針已經在上面被修改,這里是查看一下。 124 cout << "address of object in heap:" << *itr << endl; 125 } 126 127 vec_data.clear(); 128 129 cout << "\n==========check objects in heap using original pointer after delete objects" << endl; 130 // 上面的vector中,已經刪除的堆中的對象。所以下面的對象的toString()操作將是錯誤的。使用此函數,會導致程序異常退出。 131 //cout << "address of class object in heap:" << p_data12 << "\tobject in heap:" << p_data12->toString() << endl; 132 //cout << "address of class object in heap:" << p_data13 << "\tobject in heap:" << p_data13->toString() << endl; 133 134 // 上面的vector中,已經刪除了堆中的對象。但是原始的指向對象的指針還是存在的,只不過是其指向的內存已經無效。 135 cout << "address of class object in heap:" << p_data12 << endl; 136 cout << "address of class object in heap:" << p_data13 << endl; 137 138 // 此處相當於去刪除一個無效的堆的對象,會導致程序異常退出。 139 //delete p_data12; 140 //delete p_data13; 141 142 // 其所指向的對象已經在vector中刪除,所以需要將其指向的地址清理掉,防止錯誤。 143 p_data12 = 0; 144 p_data13 = 0; 145 146 cout << "process end " << (void*)&main << endl; 147 148 // 程序退出前,會自動清理掉棧中的對象。 149 150 return 0; 151 }
程序的輸出結果:
process begin at 002D170D
==========test class object in stack
CData() [sequence:0 | remark:default string] 008FF9D8
address of object in stack:008FF9D8 defalut object elements:[sequence:0 | remark:default string]
address of object in stack:008FF9D8 after set object elements:[sequence:11 | remark:baby test]
==========test class object in heap
CData(int i,string &s) [sequence:12 | remark:baby test] 00906BB8
address of pointer of class object in stack:008FF9CC address of class object in heap:00906BB8 object in heap:[sequence:12 | remark:baby test]
CData(int i,string &s) [sequence:13 | remark:baby test] 00902F30
address of pointer of class object in stack:008FF9C0 address of class object in heap:00902F30 object in heap:[sequence:13 | remark:baby test]
==========vector test. object in heap
show vector's msg
address of element in vector:0090B8E8
object address in heap:00906BB8 object msg in heap:[sequence:12 | remark:baby test]
address of element in vector:0090B8EC
object address in heap:00902F30 object msg in heap:[sequence:13 | remark:baby test]
address of element in vector:0090B8F0
object address in heap:00906BB8 object msg in heap:[sequence:12 | remark:baby test]
address of element in vector:0090B8F4
object address in heap:00902F30 object msg in heap:[sequence:13 | remark:baby test]
==========check objects in heap after clear vector
address of class object in heap:00906BB8 object in heap:[sequence:12 | remark:baby test]
address of class object in heap:00902F30 object in heap:[sequence:13 | remark:baby test]
==========delete object in heap using vector iterator
delete object:00906BB8
~CData() 00906BB8
delete object:00902F30
~CData() 00902F30
vector length is 2
==========check objects in heap using vector after delete objects
address of object in heap:00000000
address of object in heap:00000000
==========check objects in heap using original pointer after delete objects
address of class object in heap:00906BB8
address of class object in heap:00902F30
process end 002D170D
~CData() 008FF9D8
