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