NO IMAGE

我們在前面講了stl中常見的容器:順序容器(string,vector,deque,stack,queue,list)和關聯式容器(set,map)。
本節主要討論一下,以上各種容器中,資料是如何傳遞的。

資料的傳遞的方式主要有一下幾種:

  • 傳值:一份資料,進行值傳遞,會在記憶體空間上開闢多份儲存空間。涉及拷貝操作。
  • 傳指標:傳遞的是資料的地址,不涉及拷貝操作。
  • 傳引用:跟傳指標一樣。

STL中資料是以值的方式進行傳遞的,STL中的元素物件都要能夠拷貝,否則無法插入STL容器中。談到拷貝,那麼不可避免的要討論一下深拷貝淺拷貝的問題。

我們先來看一段程式碼:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Teacher{
public:
int age;
char * name;
Teacher(char *name, int age){
int len = strlen(name)   1;
this->name = new char[len];
strcpy(this->name, name);
this->age = age;
}
~Teacher(){
if (this->name != NULL){
delete[] this->name;
}
this->age = 0;
}
};
void test(){
Teacher t1("aaa", 1), t2("bbb", 2);
vector<Teacher> v;
v.push_back(t1);
v.push_back(t2);
}
int main(){
test();
return 0;
}

思考一下,這段程式碼為什麼出錯了?
因為C STL中的copy是淺copy。只拷貝的字元指標name,卻沒有copy字元指標所指向的堆記憶體空間
。所以在程式結束的時候,vector容器中的兩個Teacher物件釋放了name指標所指向的堆記憶體空間,輪到物件t1和t2釋放name所指向的記憶體空間時,發現找不到該記憶體空間了。於是程式崩潰。

解決方法就是過載拷貝建構函式和運算子=。將字元指標name所指向的堆記憶體空間也拷貝過來。
程式碼如下:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Teacher{
public:
int age=0;
char * name="aiden";
Teacher(char *name, int age){
int len = strlen(name)   1;
this->name = new char[len];
strcpy(this->name, name);
this->age = age;
}
Teacher(const Teacher & t){
int len = strlen(t.name)   1;
this -> name = new char[len];
strcpy(this->name, t.name);
this->age = t.age;
}
Teacher& operator=(Teacher &t){
int len = strlen(t.name)   1;
this->name = new char[len];
strcpy(this->name, t.name);
this->age = t.age;
return *this;
}
~Teacher(){
if (this->name != NULL){
delete[] this->name;
}
this->age = 0;
}
};
void test(){
Teacher t1("aaa", 1), t2("bbb", 2);
vector<Teacher> v;
v.push_back(t1);
v.push_back(t2);
vector<Teacher>::iterator i = v.begin();
while (i != v.end()){
cout << "Teacher's name is: " << i->name << " " << "Teacher's age is: " << i->age << endl;
i  ;
}
cout << endl;
}
int main(){
test();
return 0;
}