子類的拷貝建構函式如何呼叫其父類的拷貝建構函式
阿新 • • 發佈:2019-02-15
class base {
public:
base(int initialvalue = 0): x(initialvalue) {}
base(const base& rhs): x(rhs.x) {}
private:
int x;
};
class derived: public base {
public:
derived(int initialvalue)
: base(initialvalue), y(initialvalue) {}
derived(const derived& rhs) // 錯誤的拷貝
: y(rhs.y) {} // 建構函式
private:
int y;
};
類derived展現了一個在所有c++環境下都會產生的bug:當derived的拷貝建立時,沒有拷貝其基類部分。當然,這個derived物件的base部分還是建立了,但它是用base的預設建構函式建立的,成員x被初始化為0(預設建構函式的預設引數值),而沒有顧及被拷貝的物件的x值是多少!
為避免這個問題,derived的拷貝建構函式必須保證呼叫的是base的拷貝建構函式而不是base的預設建構函式。這很容易做,只要在derived的拷貝建構函式的成員初始化列表裡對base指定一個初始化值:
class derived: public base {
public:
derived(const derived& rhs): base(rhs), y(rhs.y) {}
...
};
現在,當用一個已有的同類型的物件來拷貝建立一個derived物件時,它的base部分也將被拷貝了。
public:
base(int initialvalue = 0): x(initialvalue) {}
base(const base& rhs): x(rhs.x) {}
private:
int x;
};
class derived: public base {
public:
derived(int initialvalue)
: base(initialvalue), y(initialvalue) {}
derived(const derived& rhs) // 錯誤的拷貝
: y(rhs.y) {} // 建構函式
private:
int y;
};
類derived展現了一個在所有c++環境下都會產生的bug:當derived的拷貝建立時,沒有拷貝其基類部分。當然,這個derived物件的base部分還是建立了,但它是用base的預設建構函式建立的,成員x被初始化為0(預設建構函式的預設引數值),而沒有顧及被拷貝的物件的x值是多少!
為避免這個問題,derived的拷貝建構函式必須保證呼叫的是base的拷貝建構函式而不是base的預設建構函式。這很容易做,只要在derived的拷貝建構函式的成員初始化列表裡對base指定一個初始化值:
class derived: public base {
public:
derived(const derived& rhs): base(rhs), y(rhs.y) {}
...
};
現在,當用一個已有的同類型的物件來拷貝建立一個derived物件時,它的base部分也將被拷貝了。