次の例を考えてみましょう
class base
{
protected :
int x = 5;
int(base::*g);
};
class derived :public base
{
void declare_value();
derived();
};
void derived:: declare_value()
{
g = &base::x;
}
derived::derived()
:base()
{}
知識によれば、基本クラスのフレンドと派生クラスのみが基本クラスの保護されたメンバーにアクセスできますが、上記の例では、次のエラーが発生します"Error C2248 'base::x': cannot access protected member declared in class "
しかし、次の行を追加すると
friend class derived;
友達として宣言すると、基本クラスのメンバーにアクセスできますが、派生クラスの宣言で基本的な間違いをしましたか?
派生クラスは、派生クラスのコンテキストを介してのみ、基本クラスの protected
メンバーにアクセスできます。一方、派生クラスは、基本クラスを介してprotected
メンバーにアクセスできません。
保護されたメンバーへのポインターが形成されるとき、その宣言で派生クラスを使用する必要があります。
struct Base { protected: int i; }; struct Derived : Base { void f() { // int Base::* ptr = &Base::i; // error: must name using Derived int Base::* ptr = &Derived::i; // okay } };
あなたになら変えられる
g = &base::x;
に
g = &derived::x;
私のコンパイラは、フィールドが初期化されていないため、デフォルト以外のコンストラクタをbase
に追加する必要があると実際に言っていました。
追加した後
base() : g(&base::x) {}
問題なくコンパイルされました。