1. 程式人生 > >C++基類私有成員會被繼承嗎

C++基類私有成員會被繼承嗎

1.派生類間接訪問基類私有成員

在類的繼承中,基類私有成員在派生類中是“不可見“的,這種”不可見“是指在派生類的成員函式中,或者通過派生類的物件(指標,引用)不能直接訪問它們。但是,不能直接訪問並不代表不能訪問。在派生類還是能夠通過呼叫基類的共有函式的方式來間接地訪問基類的私有成員,包括私有成員變數和私有成員函式。考察如下程式。

#include <iostream>
using namespace std;

class A
{
    int i;
    void privateFunc()
    {
        cout<<"this is a private function of base class"
<<endl; } public: A(){i=5;} int getI() { return i; } void usePrivateFunc() { privateFunc(); } }; class B:public A { public: void printBaseI() { cout<<getI()<<endl; } void usePrivateFunction() { usePrivateFunc(); } }; int
main() { B b; b.printBaseI(); b.usePrivateFunction(); }

程式輸出結果:

5
this is a private function of base class

在類B中,由於基類A的成員變數i和成員函式privateFunc()都是私有的,所以在類B的成員函式中無法直接訪問到它們。但是,由於類A的公有成員函式getI()可以訪問到私有成員變數i,而usePrivateFunction()可以訪問私有成員函式privateFunc(),所以在類B中通過呼叫函式getI()和usePrivateFunc()就可以簡介訪問基類A中的私有成員。

2.私有成員會被繼承嗎

如果基類中並沒有提供訪問私有成員的公有函式,那麼其私有成員是否“存在“呢?還會不會被繼承呢?其實,這些私有成員的確是存在的,而且會被繼承,只不過程式設計師無法通過正常的渠道訪問到它們。考察如下程式,通過一種特殊的方式訪問了類的私有成員。

#include <iostream>
using namespace std;

class A
{
    int i;
    void privateFunc()
    {
        cout<<"this is a private function of base class"<<endl;
    }

public:
    A(){i=5;}
};

class B:public A
{
public:
    void printBaseI()
    {
        int* p=reinterpret_cast<int*>(this);//獲取當前物件的首地址
        cout<<*p<<endl;
    }

    void usePrivateFunction()
    {
        void (*func)()=NULL;
        _asm
        {
            mov eax,A::privateFunc;
            mov func,eax;
        }
        func();
    }
};

int main() 
{
    B b;
    b.printBaseI();
    b.usePrivateFunction();
}

程式輸出結果:

5
this is a private function of base class

(1)雖然類A沒有提供訪問私有成員變數i的公有方法,但是在類A(以及類A的派生類)物件中個,都包含變數i。

(2)雖然類A並沒有提供訪問私有成員函式privateFunc()的公有函式,但是在程式程式碼區依然存有函式privateFunc()的程式碼,通過內聯彙編獲取該函式的入口地址,仍然可以順利呼叫。

綜上所述,類的私有成員一定存在,也一定被繼承到派生類中,從大小也可以看出派生類包含了基類的私有成員,讀者可自行考證。只不過收到C++語法的限制,在派生類中訪問基類的私有成員只能通過間接的方式進行。

參考文獻

[1]陳剛.C++高階進階教程[M].武漢:武漢大學出版社,2008[8.1節]