首頁>技術>

C++類封裝的受保護成員,如果不考慮繼承的話,我們可以認為類有兩類使用者:類的普通使用者(類使用者,類例項化後對類成員的訪問)和類的實現者(類成員函式對其它成員的訪問)。

類的普通使用者編寫的程式碼使用類的物件,這部分程式碼只能訪問類的公有(介面)成員。

類的實現者則負責編寫類的成員和友元的程式碼,成員和友元既能訪問類的公有部分,也能訪問類的私有(實現)部分。

如果進一步考慮繼承的話就會出現第三種使用者,即派生類實現者。基類把它希望派生類能夠使用而不希望普通使用者使用的部分宣告成受保護的。基類的普通使用者不能訪問受保護的成員,而派生類及其友元可以訪問。對於基類的private成員,派生類雖然有繼承到其記憶體空間,但其本身及友元都不可訪問。另外,如果是private繼承,派生類本身的實現者的使用規則不變,但對派生類的派生類及派生類的普通使用者來說,private繼承的都成了private了,不能被訪問了。而protected繼承則稍有區別,protected繼承的public也成了protected了,只限制類的普通使用者,派生類不限制。

private資料成員雖然不能被直接訪問,但透過間接取地址,可以間接訪問:

#include <iostream>using namespace std;class B{public:    B():bx(1),by(2),bz(3){}    int bf(){ return bz;} // 類的實現者    int bx;protected:    int by;private:    int bz;};class D:private B{public:    D():B(),dx(4),dy(5),dz(6){}    int df(){        int* p=reinterpret_cast<int*>(this);//獲取當前物件的首地址        return bx+by+*(p+2)+dx+dy+dz; // 派生類實現者(對基類的使用)    }    int dx;protected:    int dy;private:	void privateFunc()	{		cout<<"this is a private function of base class"<<endl;	}    int dz;};class E:private D{public:    E():D(){}    int ef(){          int* p=reinterpret_cast<int*>(this);//獲取當前物件的首地址        //return bx+by+*(p+2)+dx+dy+*(p+5); //21 public or protected or e:private D        return *p+*(p+1)+*(p+2)+*(p+3)+*(p+4)+*(p+5); // public or protected    }	void usePrivateFunction()	{        /*		void (*func)()=NULL;		__asm		{			mov eax,D::privateFunc;			mov func,eax;		}        */	}};int main(){    E e;    cout<<"孫物件e的int成員數量:"<<sizeof(e)/sizeof(int)<<endl;    cout<<e.ef()<<endl; // 類的普通使用者(使用公共成員)    D d;    cout<<d.df()<<endl;    int* p=reinterpret_cast<int*>(&d);//獲取當前物件的首地址    cout<<*(p+3)<<endl;    while(1);    return 0;}/*輸出:孫物件e的int成員數量:621214*/

ref:

Lippman 《C++ primer》

https://blog.csdn.net/K346K346/article/details/49652209

-End-

4
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 「微服務閘道器」SpringCloud Gateway原理與實戰