C++ 基類建構函式帶引數的繼承方式及派生類的初始化
阿新 • • 發佈:2019-01-08
在定義類的時候,會遇到基類的建構函式帶引數,而子類子類建構函式不帶引數,這時候如果以程式碼 a 的方式建立派生類則會出錯。
程式碼 a:
class A
{
public:
A(int x, int y):i(x),j(y){ }
private:
int i, j;
};
class B:public A
{
public:
B() { cout << "init B" << endl; }
};
在建立B類物件時,編譯出錯:
C:\Documents and Settings\admin\桌面\Text1.cpp(104) : error C2512: ‘A’ : no appropriate default constructor available
解決這個問題應該在A的建構函式中顯式呼叫基類的帶參建構函式。因為在基類中定義了帶參建構函式,編譯器不會提供預設建構函式。(或者可以在基類中增加一個不帶引數的建構函式)這個問題將解決。
程式碼 b 採用的是呼叫基類帶參建構函式的方式:
程式碼 b:
class A
{
public:
A(int x, int y) :i(x),j(y){ }
private:
int i, j;
};
class B:public A
{
public:
B():A(10,20) { cout << "init B" << endl; }
};
//即在建構函式的後面增加一個冒號,後面是基類的建構函式。這種方式同樣可以用來初始化類中的常量(初始化列表)。
通過在基類中增加一個不帶引數的建構函式:
程式碼 c:
class A
{
public:
A(int x, int y):i(x),j(y){ }
A(); //不帶引數的建構函式
private:
int i, j;
};
class B:public A
{
public:
B():A(10,20) { cout << "init B" << endl; }
};
綜合例子:
#include <iostream>
using namespace std ;
class A {
public:
A(int ii):i(ii){
cout<<"A::A()"<<endl;
}
~A(){
cout<<"A::~A()"<<endl;
}
void print(){
cout<<"A::print() "<<i<<endl;
}
void print(int i){
cout<<"now i ="<<i<<endl;
print();
}
void set(int ii){
i = ii;
cout<<"set("<<i<<")"<<endl;
}
private:
int i;
};
class B : public A {
public:
B(int a):A(15),t(a){ //父類建構函式有引數,子類構造的時候需對父類進行初始化
cout<<"B::B()"<<endl;
}
~B(){
cout<<"B::~B()"<<endl;
}
void print(){
cout<<"B::print()"<<endl;
}
void f(){
cout<<t<<endl;
set(20);
//i = 10; error: public繼承不能直接修改基類裡的private成員
print();
}
private:
int t;
}; //public繼承,可以訪問,不能直接修改基類裡的private成員.
int main()
{
B b(1000);
b.f();
b.print();
b.set(10);
cout<<"test beginning!"<<endl;
b.print();
b.f();
b.A::print(200); //C++在父類和子類同時定義了一個函式名和引數表都一樣的時候,只有子類一個函式,父類的同名函式全部被隱藏
cout<<"test over!"<<endl;
return 0;
}