c++是物件導向的基石,類具有可派生性。派生類可以自動獲得基類的成員變數和介面,不過基類的非虛函式則無法再被派生類使用了。如果派生類要使用基類的建構函式,通常需要在建構函式中顯示宣告。
例如:
struct a };
struct b : a
};
b派生於a,b又在建構函式中呼叫a的建構函式,從而完成了建構函式的"傳遞"。
struct a };
struct b : a
int d;
};
上面**中,派生於結構體a的結構體b擁有乙個成員變數d,那麼在b的建構函式b(int i)中,我們可以在初始化其基類a的同時初始化成員d,從這個意義上講,這樣的建構函式設計是合情合理的。但是者對於比較龐大的類來說,就不太適合了,類很龐大,我們需要寫很多"透傳"的建構函式。
例如:
struct a
a(float f, int i, const char* c)
{}};
struct b : a
b(double d, int i) : a(d, i){}
b(double f, int i, const char* c) : a(f, i, c){}
virtual void extrainte***ce(){}
};
上面的**中,我們可以看到,基類a中的建構函式又很多個版本,而繼承a的派生類b中實際上只新增了乙個extrainte***ce介面,那麼如果我們在b中要想擁有a這樣多的構造方法的話,就必須一一"透傳"各個介面,這是很不方便的。
想要解決以上問題,其實c++中已經有乙個好用的規則,就是如果派生類要使用基類的成員函式的話,可以通過using宣告來完成;**如下:
#include using namespace std;
struct base
};struct derived : base
}int main()
在c++ 11中,以上這個想法被擴充套件到了建構函式上,子類可以通過使用using宣告來宣告整合類的建構函式。那麼要改造透傳的**接很簡單了。
struct a
a(float f, int i, const char* c)
{}};
struct b : a
};
這裡我們通過using a::a的宣告,把基類中的建構函式悉數繼承到派生類b中,這樣我們就可以摒棄透傳了。c++11標準繼承建構函式被設計為跟派生類中的各種類預設函式(預設構造,析構,拷貝構造等)一樣,是隱式宣告的。不過繼承建構函式只會初始化基類中的成員變數,對於派生類的成員變數,則無能為力。
struct a
a(float f, int i, const char* c)
{}};
struct b : a
};int main()
上面**使用兩個c++ 11的特性來解決繼承構造無法初始化派生類成員變數的問題,
由於繼承構造是隱式的,c++類中也有很多隱式函式,因此傳值得時候必須注意
繼承建構函式的衝突的情況:
struct a };
struct b };
struct c : a, b
a和b的建構函式會導致c中重複定義相同型別的繼承建構函式。這種情況下,可以通過顯示定義繼承類的衝突建構函式,阻止隱式生成相應的繼承建構函式來解決衝突。
例如:
struct c : a, b
}
此外,我們還要了解一些規則,如果基類的建構函式被宣告為私有成員函式,或者派生類是從基類中繼承的,那麼就不能夠在派生類中宣告繼承建構函式。當然,如果一旦使用了繼承建構函式,編譯器就不會再為派生類生成預設建構函式了,對於一下**,必須注意繼承建構函式中沒有包含乙個無引數的版本。
struct a };
struct b : a
;b b;
C 11 繼承建構函式
繼承建構函式 基類有多個不同版本的建構函式,子類必須對應建構函式來進行 透傳 如 class base base double d,int i void fun float d class derived public base derived double d,int i base d,i voi...
C 11之繼承建構函式
1.1.3 using 宣告使用範圍 2.c 11使用using來繼承基類建構函式 3.繼承建構函式可能遇到的問題 當類b繼承於類a的時候,它會繼承類a中的資料成員與普通成員函式。但是某些成員函式是無法被繼承下來的,比如類a 基類 中的合成建構函式 包括構造 析構 拷貝等等 因此,類b在初始化類a的...
c 11 繼承構造
define crt secure no warnings include include include include c 11允許派生類繼承基類的建構函式 預設建構函式 複製建構函式 移動建構函式除外 注意 繼承的建構函式只能初始化基類中的成員變數,不能初始化派生類的成員變數 如果基類的建構函...