![](/img/trans.png)
[英]How to initalize nested class members in outer class constructor in 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())。
迭代器的解決方案:將迭代器設為公共。
C
是B
嵌套類。 嵌套類無法訪問封閉類的私有成員和受保護成員。 這就是代碼無法編譯,並正確地給出編譯錯誤的原因。
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.