C++繼承三種方式

C++中的繼承分爲三種繼承方式:

public,protected,private。

繼承會導致父類中的成員訪問屬性發生變化。

繼承機制中,子類訪問父類成員方式

不管什麼繼承,父類的private成員始終爲父類私有。

public繼承:父類的public和protected成員在子類中訪問屬性不變

private繼承:父類的public和protected成員在子類中變成private

protected繼承:父類public和protected成員在子類中變成protected

例子1:

class Base{

public:

Base()

{

printf(“Base構造函數\n”);

}

~Base()

{

printf(“Base析構函數\n”);

}

};

class Derive : public Base{

public:

Derive()

{

printf(“Derive構造函數\n”);

}

~Derive()

{

printf(“Derive析構函數\n”);

}

};

int main()

{

Base* d = new Derive();

delete d;

return 0;

}1234567891011121314151617181920212223242526272829303132

這段代碼輸出:

Base構造函數

Derive構造函數

Base析構函數123

分析:

主函數中Base* d = new Derive(),new一個Base類型的指針實例。

因爲子類是繼承父類的,所以調用子類的構造方法之前,必然會首先調用父類的構造方法(初始化父類的一些成員變量);

new出來的實例是Base類型的,所以delete時,會調用Base的析構函數。

例子2:

將例1中的主函數變爲:

Derive* d = new Derive();

delete d;12

輸出:

Base構造函數

Derive構造函數

Derive析構函數

Base析構函數1234

分析:

構造函數的調用順序與例1一樣,不同的是這次new出來的實例指向了Derive類型的指針,因爲Derive繼承了Base類中成員變量和函數,所以生成Derive類型實例的同時,必然會產生Base類型的實例。

根據析構函數的調用順序,先構造後析構,因此輸出結果如上。

例子3:

將例1中Base的析構函數改爲virtual函數:

virtual ~Base()

{

printf(“Base析構函數\n”);

}1234

輸出結果:

Base構造函數

Derive構造函數

Derive析構函數

Base析構函數1234

可以看出,輸出結果與例2一樣。

構造函數的調用順序與上面的例子一樣,這次因爲Base的析構函數成了虛函數,父類指針指向子類的實例,所以在調用父類的析構函數時,會有多態效果,實際調用的是子類的析構函數。

delete d的時候,先析構繼承類,再析構父類。

實際上,我們在使用類的析構函數時,一般都把析構函數設爲虛函數。

在實現多態時,當用基類操作派生類,在析構時防止只析構基類而不析構派生類的狀況發生。

例子4:

class Base{

public:

Base(int num)

{

num_ = num;

printf(“Base構造函數,num=%d\n”, num_);

}

~Base()

{

printf(“Base析構函數\n”);

}

virtual void Show()

{

printf(“Show:%d\n”,num_);

}

protected:

int num_;

};

class Derive : public Base{

public:

Derive(int num, int age):Base(num)

{

age_ = age;

printf(“Derive構造函數,age=%d\n”, age_);

}

~Derive()

{

printf(“Derive析構函數\n”);

}

void Show()

{

printf(“Show, num:%d, age:%d\n”, num_, age_);

}

private:

int age_;

int num_;

};

int main()

{

Base* d = new Derive(1,3);

d->Show();

delete d;

return 0;

}12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152

輸出:

Base構造函數,num=1

Derive構造函數,age=3

Show, num:-842150451, age:3

Base析構函數1234

子類的成員變量和函數名是可以跟父類相同的。

繼承類的構造函數需要“繼承”基類的構造函數,因爲在構造子類時,必然要構造基類。

用:符號來“繼承”。

如:Derive(int num, int age):Base(num)

當繼承類的成員變量名與基類相同時,以繼承類爲準。

當基類的成員函數修飾爲virtual函數時,指向基類的繼承類實例調用函數時,調用的是繼承類的方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章