1. 程式人生 > >C++ 基類建構函式帶引數的繼承方式及派生類的初始化

C++ 基類建構函式帶引數的繼承方式及派生類的初始化

在定義類的時候,會遇到基類的建構函式帶引數,而子類子類建構函式不帶引數,這時候如果以程式碼 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; }