1. 拷貝構(gòu)造函數(shù)
功能:可以讓一個(gè)對(duì)象給另一個(gè)對(duì)象進(jìn)行初始化,將該對(duì)象的內(nèi)容拷貝過(guò)去。不寫(xiě)時(shí)編譯器會(huì)自動(dòng)生成一個(gè)默認(rèn)的拷貝構(gòu)造函數(shù),默認(rèn)的拷貝構(gòu)造函數(shù)會(huì)將源對(duì)象的內(nèi)容按字節(jié)拷貝到新對(duì)象。
例子:
Rect::Rect(const Rect& r)
{
width = r.width;
height = r.height;
}
淺拷貝和深拷貝
淺拷貝:
class TestClass {
string *s;
public:
TestClass(const TestClass& other);
};
TestClass::TestClass(const TestClass& other) {
s = other.s;
}
經(jīng)過(guò)淺拷貝之后,兩個(gè)對(duì)象中的s都會(huì)指向同一塊空間,一個(gè)對(duì)象對(duì)其進(jìn)行修改,會(huì)影響到另一個(gè)對(duì)象,且它們?cè)谖鰳?gòu)的時(shí)候容易產(chǎn)生二次刪除的錯(cuò)誤。
深拷貝:
class TestClass {
string *s;
public:
TestClass(const TestClass& other);
};
TestClass::TestClass(const TestClass& other) {
s = new string(*other.s);
}
經(jīng)過(guò)深拷貝之后,兩個(gè)對(duì)象中的s指向的是兩塊不同的空間,它們的內(nèi)容是相同的,但是互不影響。
2. 賦值函數(shù)
功能:在使用賦值運(yùn)算符將一個(gè)對(duì)象賦值給另一個(gè)對(duì)象的時(shí)候會(huì)被調(diào)用。編譯器的默認(rèn)實(shí)現(xiàn)也是按字節(jié)拷貝。
與拷貝構(gòu)造注意區(qū)分:
TestClass a;
TestClass b = a; // 拷貝構(gòu)造
TestClass c;
c = a; // 賦值
在賦值函數(shù)中,需要判斷自身是否與賦值源是否是同一個(gè)對(duì)象:
TestClass& operator=(const TestClass& other) {
if (this == &other) {
return *this;
}
delete s;
s = new string(*other.s);
return *this;
}
如果不加這層判斷,將自己賦值給自己的時(shí)候容易出錯(cuò),因?yàn)樵趫?zhí)行delete s時(shí),會(huì)將自身的s釋放,之后再進(jìn)行s = new string(*other.s)時(shí)就會(huì)出錯(cuò),因?yàn)榇藭r(shí)other.s其實(shí)就是自身的s。
3. 析構(gòu)函數(shù)
功能:在一個(gè)對(duì)象要被銷(xiāo)毀的時(shí)候會(huì)被調(diào)用。在析構(gòu)函數(shù)中一般進(jìn)行資源的清理和釋放等等。
例子:
TestClass::~TestClass() {
delete s;
}
4. 堆與棧
函數(shù)中的局部變量,都在棧上創(chuàng)建,儲(chǔ)存在棧上,當(dāng)離開(kāi)函數(shù)的作用域時(shí),棧空間會(huì)被回收,棧上的對(duì)象也都會(huì)被銷(xiāo)毀。而動(dòng)態(tài)分配出來(lái)的內(nèi)存,都會(huì)存放在堆空間中,不會(huì)被自動(dòng)回收,需要手動(dòng)進(jìn)行回收。
int main() {
int a; // 棧上
int *c = new int(1); // 堆上
delete c; // 進(jìn)行手動(dòng)空間回收
return 0;
}
5. 模板
功能:使類(lèi)或者函數(shù)可以應(yīng)對(duì)于多種類(lèi)型的情況。
例子:
template<typename T, int N>
class Container {
T data[N];
};
Container<int, 10> a;
Container<double, 20> b;
這樣Container這個(gè)類(lèi)就可以靈活存儲(chǔ)各種類(lèi)型的元素。
template<typename T>
const T& max(const T& a, const T& b) {
return a < b ? b : a;
}
max(1, 2);
max(1.0, 2.0);
這樣max函數(shù)就可以靈活應(yīng)對(duì)于不同的類(lèi)型。