次のコードはC++標準で有効ですか?構造体BがAの名前空間にあるため、C::Bが機能するのは奇妙です。ただし、gccでは正常にコンパイルされます。
struct A { struct B {}; };
struct C : public A::B {};
struct D : public C::B {};
これが標準準拠のC++である場合、この構成の妥当なアプリケーションは何ですか?ありがとう。
次のコードはC++標準で有効ですか?構造体BがAの名前空間にあるため、C::Bが機能するのは奇妙です。ただし、gccでは正常にコンパイルされます。
struct A { struct B {}; };
struct C : public A::B {};
struct D : public C::B {};
これが標準準拠のC++である場合、この構成の妥当なアプリケーションは何ですか?ありがとう。
はい、有効なC++です。独自のスコープ内のクラス(つまり、両方B
とB::B
同じクラスを参照B
)、およびクラスの親クラスは独自のスコープ内にあります。したがって、B
はのC
スコープ内B
にあり、独自のスコープ内にあるため、C::B
はを参照しB
ますA::B
。
(補足:名前空間とスコープを混同しないでください。)
C++03§9パラグラフ2は次のように述べています。
クラス名は、クラス名が表示された直後に宣言されているスコープに挿入されます。クラス名は、クラス自体のスコープにも挿入されます。これは、注入されたクラス名として知られています。アクセスチェックの目的で、注入されたクラス名は、パブリックメンバー名であるかのように扱われます。
これは標準準拠のC++です。
(スコープ解決による)ネストされたクラスの合理的なアプリケーションは、pImplデザインパターンです(ただし、ネストされたクラスを示さない方法で実装できますが、ここではネストされたクラスを示すことを選択します)。注:継承は混乱を招く可能性のある側面の1つですが、実際の概念はネストされたクラスのスコープ解決です。
//ExposedClass in Exposed.h
class CExposedClass
{
public:
CExposedClass();
~CExposedClass();
void doThis();
void doThat();
private:
class CXImpl;
CXImpl *pImpl;
};
//ExposedClass Impl in Exposed.cpp
#include "Exposed.h"
class CExposedClass::CXImpl
{
int someData;
};
CExposedClass::CExposedClass():pImpl(new CXImpl()){}
CExposedClass::~CExposedClass(){delete pImpl;}
void CExposedClass::doThis(){}
void CExposedClass::doThat(){}
あるクラスのスコープ内で定義されたクラスは、スコープ解決を使用して別のスコープからアドレス指定されます。