釋義:
- 構(gòu)造函數(shù):初始化對(duì)象的數(shù)據(jù)成員的一種函數(shù)。
- 拷貝構(gòu)造函數(shù):以本類的對(duì)象引用作為參數(shù)的構(gòu)造函數(shù),目的是拷貝對(duì)象。
- 運(yùn)算符重載:重新定義運(yùn)算符行為,用以適應(yīng)不同的數(shù)據(jù)類型,本質(zhì)為函數(shù)重載。
示例:
下面這個(gè)簡(jiǎn)單的例子分別描述了帶參構(gòu)造函數(shù)、拷貝構(gòu)造函數(shù)和賦值運(yùn)算符重載。
class A{
public:
int a;
//constructor
A(int a_tmp){
a = a_tmp;
}
//copy constructor
A(const A& A_tmp){
a = A_tmp.a;
}
//member assignment operator
A& operator=(const A& A_tmp){
a = A_tmp.a;
return *this;
}
}
//non-member operator overload
A operator+(const A& A1,const A& A2){
A A_tmp;
A_tmp.a = A1.a+A2.a;
return A_tmp;
}
思考:
- 拷貝構(gòu)造函數(shù)的理解:
- 拷貝構(gòu)造函數(shù)的重點(diǎn)是構(gòu)造函數(shù),因此copy ctor只有在變量的定義處才會(huì)被調(diào)用,本質(zhì)還是一種構(gòu)造函數(shù)。
- 如果沒有顯式定義拷貝構(gòu)造函數(shù),那么編譯器會(huì)為類自動(dòng)定義一個(gè)按位拷貝的默認(rèn)拷貝構(gòu)造函數(shù)。需要注意默認(rèn)拷貝構(gòu)造函數(shù)只會(huì)對(duì)成員變量做簡(jiǎn)單的賦值運(yùn)算來完成拷貝動(dòng)作,因此對(duì)于指針型變量會(huì)出現(xiàn)淺拷貝的問題。(淺拷貝:src和dst是同一塊內(nèi)存區(qū)域;深拷貝:src和dst不在同一塊內(nèi)存區(qū)域。)
- 禁止拷貝構(gòu)造函數(shù):將拷貝構(gòu)造函數(shù)聲明為private可以禁止使用拷貝構(gòu)造函數(shù)。一般而言,將構(gòu)造函數(shù)聲明為private都可以禁止調(diào)用。這就是單例模式的實(shí)現(xiàn)方式。
- 對(duì)于B:A這種派生類,B的默認(rèn)構(gòu)造函數(shù)會(huì)調(diào)用A的默認(rèn)構(gòu)造函數(shù),如果重載了B的構(gòu)造函數(shù),若需要指定A的構(gòu)造函數(shù),則需要顯式調(diào)用,否則會(huì)調(diào)用A的默認(rèn)構(gòu)造函數(shù)。例如如果要調(diào)用A的拷貝構(gòu)造函數(shù),則需要這樣寫:
B(const B& B_tmp):A(B_tmp){
...
}
- 運(yùn)算符重載的理解:
- 為什么運(yùn)算符重載的返回值大多都是引用之一:原理上來說返回值可以為任何類型,比如可以為基本類型、類或者void,但是基于兩個(gè)方面考慮,一方面是為了便于連續(xù)運(yùn)算,比如a=b=c,b=c運(yùn)算完為了能繼續(xù)給a賦值,=運(yùn)算符會(huì)返回左值b,這里的左值可以是對(duì)象也可以是對(duì)象的引用。但是,另一方面,如果返回了對(duì)象,那么在函數(shù)返回后會(huì)調(diào)用構(gòu)造函數(shù)創(chuàng)建臨時(shí)變量用于存儲(chǔ)返回值進(jìn)行下一次a=運(yùn)算,相比返回對(duì)象引用開銷更大,因此返回對(duì)象的引用是性能較好而且更通用的做法。
- 為什么運(yùn)算符重載的返回值大多都是引用之二:實(shí)際上返回引用意味著有能力返回左值,C++ 中函數(shù)可以返回左值的功能對(duì)實(shí)現(xiàn)一些重載的操作符是非常重要的,比如方括號(hào)運(yùn)算符[],返回引用意味著能進(jìn)行類似
myVector[2] = 3.5
這樣的操作。 - 注意成員運(yùn)算符重載和非成員運(yùn)算符重載的差異,他們的參數(shù)個(gè)數(shù)是不一樣的,見上述代碼。
- 對(duì)于B:A這種派生類,運(yùn)算符重載需要顯式調(diào)用A的對(duì)應(yīng)運(yùn)算符,否則A類內(nèi)部不會(huì)發(fā)生任何改變。例如:
B& operator+(const B& B_tmp){
A:operator+(B_tmp);
...
return *this;
}