元素為指針的vector的使用說明


該程序演示了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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM