嵌套類

   對嵌套類的若干說明:

  1、從作用域的角度看,嵌套類被隱藏在外圍類之中,該類名只能在外圍類中使用。如果在外圍類的作用域內使用該類名時,需要加名字限定。

  2、從訪問權限的角度來看,嵌套類名與它的外圍類的對象成員名具有相同的訪問權限規則。不能訪問嵌套類的對象中的私有成員函數,也不能對外圍類的私有部分中的嵌套類建立對象。

  3、嵌套類中的成員函數可以在它的類體外定義。

  4、嵌套類中說明的成員不是外圍類中對象的成員,反之亦然。嵌套類的成員函數對外圍類的成員沒有訪問權,反之亦然。國此,在分析嵌套類與外圍類的成員訪問關係時,往往把嵌套類看作非嵌套類來處理。

       5、在嵌套類中說明的友元對外圍類的成員沒有訪問權。

  6、如果嵌套類比較複雜,可以只在外圍類中對嵌套類進行說明,關於嵌套的詳細的內容可在外圍類體外的文件域中進行定義。

 

 

嵌套類的訪問問題:

C++嵌套類只是語法上的嵌套。然而在實踐過程中,卻並非如此。
Ex:


class A
{
public: 
    static int a;
    class A1
    {
        void output()
        {
          cout<<a<<endl; //instead of A::a;
        }
    };
 
};
int A::a;

可見,類 A1 嵌入A後訪問A的靜態變量不寫外圍域沒有任何問題,從編譯的角度看,此時位於A::的作用域內,在符號表中是可以找到a的(注意,a必須爲static的)。這一點,與分開寫的兩個類明顯不同

還有一個特殊之處,見如下代碼:


 

Ex:

class A
{
private:
    int a;
    class A1
    {
        void output(A aObject)
        {
          cout<<aObject.a<<endl; //instead of A::a;
        }
    };
 
};

 


這段代碼在VC中不能編譯通過,但在DEV-C++是可以的,也就是不同的編譯對於嵌套類是否能訪問外圍類的私有成員的定義是不一致的。

嵌套類的不同作用域同名問題:

 

class A
{
public: 
    static int a;
    class A1
    {
        static int a;
        int    void output()
        {
          cout<<a<<endl; //instead of A::a;
        }
    };
 
};
int A::a=3;
int A::A1::a=4;

輸出內部的a沒有問題,如果要訪問外部的,使用A::a指明作用域就可以,而且在嵌套類中,可以定義靜態的成員。
用類似A::A1::a就可以訪問.
先看一下Java的情況
Ex:


//this is a Java class
class A
{
    private int c=2;
    class A1
    {
        int c=3;
        void output()
        {
            System.out.println(this.c);
            System.out.println(A.this.c);
        }
    }
}


由定義就可看出,Java的定義是動態定義的,是基於this指針的,因此,嵌套類不只在語法上,在語義上也有隸屬關係,外圍類的成員,包含私有成員,對於內部類也是可見的。因此內部非Static的類不能有Static成員,且這樣的內部類只有在外層的對象建立後才能對建立,所以你可以這麼建立對象:
Ex:


 A a = new A();
 A.A1 aa = a.new A1();

或者:
Ex:
 
A.A1 aa = new A().new A1(); //使用匿名對象

如果是靜態嵌套類
Ex:

 


//this is a Java class
class A
{
    private int c=2; //(1)
    static class A1
    {
      static int c=3;
        void output()
        {
            //System.out.println(this.c); //work well <--> A.A1.c; 這個結果由編譯靜態成生和動態加載相對地址理論輕鬆解釋
            //System.out.println(A.this.c);// (can't work) ,很明顯要求外圍對象存在,把(1)改成static 的可以通過
            System.out.println(c);  //work well
        }
    }
}


對比上面Java的定義,可見C++中的黓認行爲和Java中的靜態類相似,由此,可以猜出C++中的類是做靜態存儲的。因此,可以輕鬆的得出如下語句也是可以的:

 


Ex:
//C++
A::A1 * a = new A::A1();
 

因此,也可以得到在 C++ 中 ,內部類也是可以有靜態對象的。 

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