問題場景
類的繼承中,如果子類想使用父類的構造函數,則需要在子類的構造函數中聲明使用父類的構造函數,例子如下:
struct A
{
A(int i){}
};
struct B:A
{
B(int i):A(i),d(i){}
int d;
};
但是如果父類中含有多種版本的構造函數,那麼子類的構造函數需要多種版本的實現,實現起來很不方便。如下例子:
struct A
{
A(int i) {}
A(double d,int i){}
A(float f,int i,const char* c){}
//...等等系列的構造函數版本號
};
struct B:A
{
B(int i):A(i){}
B(double d,int i):A(d,i){}
B(folat f,int i,const char* c):A(f,i,e){}
//......等等好多個和基類構造函數相應的構造函數
};
解決方法
通過使用using方式來解決這個問題。方式如下:
struct A
{
A(int i) {}
A(double d,int i){}
A(float f,int i,const char* c){}
//...等等系列的構造函數版本號
};
struct B:A
{
using A::A;
//關於基類各構造函數的繼承一句話搞定
//......
};
int main()
{
B b(356);//使用方式
}
這樣會降低開發者的開發成本,使用起來更加的方便一些。
注意事項
- 對於繼承構造函數來說,參數的默認值是不會被繼承的,並且,默認值會導致基類產生多個構造函數版本號(即參數從後一直往前面減。直到包括無參構造函數,當然假設是默認複製構造函數也包括在內),這些函數版本號都會被派生類繼承。
當派生類擁有多個基類時,多個基類中的部分構造函數可能導致派生類中的繼承構造函數的函數名。例如:
struct A { A(int){} }; struct B { B(int){} }; struct C:A,B { using A::A; using B::B; };
上述代碼中的A和B的構造函數會導致C中會重複定義相同類型的繼承構造函數。
假設基類的構造函數被聲明爲私有構造函數或者派生類是從基類虛繼承的,那麼就不能在派生類中聲明繼承構造函數。
- 假設一旦使用了繼承構造函數,編譯器就不會爲派生類生成默認構造函數。