C 之內部類(巢狀類)與外部類及友元

2022-05-05 09:27:07 字數 2974 閱讀 2923

先上**:

1

class

outer25

private:6

intm_outerint;

7public:8

//內部類定義開始

9class

inner

1013

private:14

intm_innerint;

15public:16

void displayin()

17} ;

18//

end內部類

19public:20

void displayout()

21};

2223

intmain()

24

如上面**所示,這種情況下,外部類與內部類其實聯絡並不大,外部類無非僅僅限定了內部類類名的作用域範圍,完全可以加上outer限定之後像使用任何其他類一樣來使用內部類,outer於inner而言僅僅是一種命名空間。

提問:上面**中,內部類(inner)成員函式(比如displayin)如何訪問外部類(outer)資料成員呢?

答:問這個問題之前,先要明白乙個事實:將來你是在乙個inner例項物件上呼叫inner的成員函式的,而所謂的「訪問外部類資料成員」這種說法是不合理的,「外部類」及任何類,只是**而已,是一種說明,從記憶體的角度來講,程式執行起來之後,**儲存在**區,所以應該問「如何訪問外部類例項的資料成員」,如此,你得先有乙個外部類例項(或者例項的指標),然後才能談訪問。

退一步講,如果你不管三七二十一,直接在inner的displayin方法裡加上這樣一行:

1 m_outerint=10;

1

intmain()

2

如果這樣你都能正常執行,天理何在?displayin中的m_outerint到底是哪個例項的資料?

所以,為了避免這樣荒唐的事情發生,語法層面就已經使得上述不可能發生:連編譯都不會通過。

提問:把上面**中的inner設定為outer的友元類之後,能解決問題嗎?

答:該提問者都不僅犯了第乙個提問者的錯誤,還誤解了友元的含義。

友元舉例:

1

class

inner;23

class

outer47

private:8

intm_outerint;

9public:10

/*//內部類定義開始

11class inner

1215

private:

16int m_innerint;

17public:

18void displayin() ;

20//end內部類

*/21

public:22

void displayout()

23friend inner;

24};

25class

inner

2629

private:30

intm_innerint;

31public:32

void displayin()

33//

友元影響的函式

34void testfriend(outer out)35

38} ;

3940

intmain()

41

內部類如果想達到友元訪問效果(直接通過例項或者例項指標來訪問例項的非公有成員),是不需要另外再宣告為friend的,原因不言自明:都已經是自己人了。

提問:內部類例項(作為外部類的資料成員)如何訪問外部類例項的成員呢?

見如下**:

1 #include 2

#define method_prologue(theclass, localclass) \

3 theclass* pthis = ((theclass*)((char*)(this) -\

4offsetof(theclass, m_x##localclass))); \56

using

namespace

std;78

class

outer912

private:13

intm_outerint;

14public:15

//內部類定義開始

16class

inner

1720

private:21

intm_innerint;

22public:23

void displayin()

24//

在此函式中訪問外部類例項資料

25void

setout()

2630

} m_xinner;

31//

end內部類

32public:33

void displayout()

34};

3536

intmain()

37

看main函式:程式執行完main函式第一句後,記憶體中便有了乙個資料塊,它儲存著out的資料,而m_xinner也在資料塊中,當然,&out和this指標(外部類)都指向該記憶體塊的起始位置,而內部類**中的this指標當然就指向m_xinner的起始記憶體了,offsetof(theclass, m_x##localclass)獲得的便是m_xinner在該記憶體塊中與該記憶體塊起始位址(這正是out的位址)的距離(偏移),即內部類this-外部類this的差值(以位元組為單位)這樣,用內部類this減去其自身的偏移,便可得到pthis。有了out的位址,基本上可以對其為所欲為了,至於為何要有char*強轉,可以go to definition of offsetof,可以看到其實現中有個關於char的轉換。

C 之內部類(巢狀類)與外部類及友元

1 class outer 2 5 private 6 int m outerint 7 public 8 內部類定義開始 9 class inner 10 13 private 14 int m innerint 15 public 16 void displayin 如果這樣你都能正常執行,天理...

Java基礎之內部類與外部類

1 外部類訪問內部類,需要建立內部類物件,才能對內部類進行訪問 2 內部類中方法訪問外部類私有屬性,也需要建立外部類物件進行訪問物件的私有屬性 3 jvm在載入具有外部類和內部類特徵的類的時候有什麼特點?package com.dong.first 關於內部類與外部類的使用 author admin...

C 突破封裝 友元和內部類

首先來看乙個date類,當我們想要過載實現 operator 和 operator 一般會在類的內部寫 class date istream operator istream in private int year int month int day 但是這樣會存在乙個問題,類中 this指標 隱含...