先上**:
1class
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;
1intmain()
2
如果這樣你都能正常執行,天理何在?displayin中的m_outerint到底是哪個例項的資料?
所以,為了避免這樣荒唐的事情發生,語法層面就已經使得上述不可能發生:連編譯都不會通過。
提問:把上面**中的inner設定為outer的友元類之後,能解決問題嗎?
答:該提問者都不僅犯了第乙個提問者的錯誤,還誤解了友元的含義。
友元舉例:
1class
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指標 隱含...