簡體   English   中英

嵌套的C ++類外部成員的訪問權限

[英]Nested C++ class outer members' access

此代碼不起作用(MS VS 2005),

b->funcA();
B::iterator iter;

無法訪問A類中聲明的受保護成員

如果我刪除D類,一切都很好地編譯。

我想知道這只是一個錯誤還是標准?

class A
{
protected:
    void funcA() {  }
    class iterator {    };
};

class D {
    class B : public A {
        class C {
            B* b;
        public:
            void funcC() {
                b->funcA();
                B::iterator iter;
            }
        };
    public:
        void funcB() {
            funcA();
        }
    };
};

謝謝!

當前的C ++標准(C ++ 03)具有以下限制,會使您的代碼格式錯誤:

嵌套類的成員對封閉類的成員沒有特殊訪問權限,也沒有對已經為封閉類授予友誼的類或函數的特殊訪問權限。 應遵守通常的准入規則(C ++ 03 11.8 / 1)。

但是,在即將推出的C ++標准(C ++ 0x)中,此規則已被顛倒過來。 該段現為:

嵌套類是成員,因此具有與任何其他成員相同的訪問權限。 封閉類的成員對嵌套類的成員沒有特殊訪問權限; 應遵守通常的訪問規則(C ++ 0x Draft N3225 11.8 / 1)。

所以,根據舊的解釋,你的代碼是不正確的,但在新的解釋下,它是正確的。 這基本上是原始C ++標准中的一個缺陷; 該缺陷在1998年被注意到並且在2001年達成了修正。您可以在CWG缺陷45中找到有關該缺陷的詳細信息。


請注意,無論您想使用哪種解釋,我認為編譯器中仍然存在錯誤。 以下是最小repro,並在使用Visual C ++ 2010時生成相同的錯誤:

class A {
protected:
    void f() { }
};

struct D {
    struct B : A {
        struct C {
            void g() { 
                B().f(); 
            }
        };
    };
};

但是,如果刪除D並將B放在全局命名空間中,編譯器將接受該代碼。

C嵌套在B中的事實不會給B的成員提供C特殊訪問權限。

funcA()的解決方案:(1)使funcA()公開。 或(2)改為調用funcB()(委托給funcA())。

迭代器的解決方案:將迭代器設為公共。

CB嵌套類。 嵌套類無法訪問封閉類的私有成員和受保護成員。 這就是代碼無法編譯,並正確地給出編譯錯誤的原因。

C ++標准(2003)以11.8美元/ 1 [class.access.nest]的形式說,

嵌套類的成員對封閉類的成員沒有特殊訪問權限 ,也沒有對已經為封閉類授予友誼的類或函數的特殊訪問權限 應遵守通常的准入規則(第11條)。 封閉類的成員對嵌套類的成員沒有特殊訪問權限; 應遵守通常的准入規則(第11條)。

標准本身的示例:

class E 
{
    int x;
    class B { };
    class I 
    {
        B b; // error: E::B is private
        int y;
        void f(E* p, int i)
        {
           p->x = i; // error: E::x is private
        }
   };
   int g(I* p)
   {
       return p->y; // error: I::y is private
   }
};

因此,根據它, D存在或不存在不應該影響任何事情。 它應該給出編譯錯誤,即使D不存在。

昨天創建了類似的主題: C ++中的內部類是自動的朋友嗎?


順便說一句,它是C ++ 03中的一個缺陷,已在C ++ 0x中得到糾正。

這在C ++ 0x中是允許的。 請參閱此對嵌套類的訪問

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM