{ public: String(const char *str = NULL); // 普通構(gòu)造函數(shù) String(const String &other); // 拷貝構(gòu)造函數(shù) ~ String(void); // 析構(gòu)函數(shù) String & operate =(const String &other); // 賦值函數(shù) private: char *m_data; // 用于保存字符串 };
String::~ Stirng(void)//析構(gòu)函數(shù) String::String(const String &other) //拷貝構(gòu)造函數(shù) String & String::operate=(const String &other) //賦值語句
{ } 說明: 1)構(gòu)造函數(shù)是一種特殊函數(shù),而拷貝構(gòu)造函數(shù)是一種特殊的構(gòu)造函數(shù)。類X的構(gòu)造函數(shù)的第一個(gè)參數(shù)必須為X&,或者const X&;除了第一個(gè)參數(shù)外,構(gòu)造函數(shù)要么不存在其他參數(shù),如果存在其他參數(shù),其他參數(shù)必須有默認(rèn)值。一個(gè)類可以有多個(gè)拷貝構(gòu)造函數(shù)。
它的形式如下: X::X(X& x) X::X(const X& x) X::X(X& x, int a = 0, int b = 1…)
2)什么時(shí)候會調(diào)用拷貝構(gòu)造函數(shù)?
以下三種情況出現(xiàn)時(shí),會調(diào)用一個(gè)類的拷貝構(gòu)造函數(shù):
a) 用一個(gè)已經(jīng)實(shí)例化了的該類對象,去實(shí)例化該類的另外一個(gè)對象;
b) 用該類的對象傳值的方式作為一個(gè)函數(shù)的參數(shù);
c) 一個(gè)函數(shù)返回值為該類的一個(gè)對象。
例如:
CA a;
// CA b(); // 不能用這種方式聲明CA的對象b!
CA c(10, 10);
CA d(c); // 情況1) -> 調(diào)用拷貝構(gòu)造函數(shù)
int anInt = someFun1(c); // 情況2) -> 調(diào)用拷貝構(gòu)造函數(shù)
CA e = someFun2(11, 11); // 情況3) -> 調(diào)用拷貝構(gòu)造函數(shù)
3)什么時(shí)候必須要顯式聲明拷貝構(gòu)造函數(shù)?
如果有成員變量以指針形式存在,涉及動態(tài)內(nèi)存分配等情況下,一定要顯式聲明拷貝構(gòu)造函數(shù)。要注意到,如果需要顯式定義拷貝構(gòu)造函數(shù),那么 通常都是需要同時(shí)定義析構(gòu)函數(shù)(因?yàn)橥ǔI婕傲藙討B(tài)內(nèi)存分配),至于是否必須重載操作符“=”,要視情況而定。
例如:
class CA {
public:
Point* _point;
public:
CA(const Point*);
// 需要增加的拷貝構(gòu)造函數(shù)
CA(const CA&);
// 需要增加的析構(gòu)函數(shù)
virtual ~CA();
// 需要增加的拷貝賦值函數(shù)
CA& operator = (const CA&);
};
int main(void) {
Point apoint(1, 2);
CA ca(&apoint);
ca.printCoordinates();
CA cb(ca); // 調(diào)用拷貝構(gòu)造函數(shù)
CA cc = cb; // 調(diào)用拷貝賦值函數(shù)
..............
}
4)缺省構(gòu)造函數(shù)、拷貝構(gòu)造函數(shù)、拷貝賦值操作符和析構(gòu)函數(shù)是特殊成員函數(shù)。
5)構(gòu)造函數(shù)不能有返回類型,也不能由virtual, const, static 和 volatile來修飾。但可以由inline來修飾,事實(shí)上隱式構(gòu)造函數(shù)就是用inline來修飾的。inline表示編譯時(shí)展開,通常速度塊;virtual表示運(yùn)行時(shí)綁定,通常意味著靈活。
6)類中存在虛函數(shù)或者有虛基類的情況下需要顯式聲明構(gòu)造函數(shù)。拷貝構(gòu)造函數(shù)也是如此。 |
|