次のコードがあります。
struct A {
protected:
A() {}
A* a;
};
struct B : A {
protected:
B() { b.a = &b; }
A b;
};
奇妙なことにコンパイルされません。犯人はb.a = &b;
割り当てです: GCC と clang の両方A()
が保護されていると文句を言いますが、B は A を継承しているため、これは問題にはなりません。
次のコードがあります。
struct A {
protected:
A() {}
A* a;
};
struct B : A {
protected:
B() { b.a = &b; }
A b;
};
奇妙なことにコンパイルされません。犯人はb.a = &b;
割り当てです: GCC と clang の両方A()
が保護されていると文句を言いますが、B は A を継承しているため、これは問題にはなりません。
の意味は、派生型は、任意のランダム オブジェクト*ではなく、独自のベースprotected
のメンバーにアクセスできるということです。あなたの場合、あなたの制御外にある のメンバーを変更しようとしている(つまり、 を設定できますが、 はできません)b
this->a
b.a
興味がある場合は、これを機能させるためのハックがありますが、より良い解決策は、コードをリファクタリングし、ハックに依存しないことです。たとえば、引数として受け取るコンストラクターを提供しA
(A*
このコンストラクターは public である必要があります)、次の初期化子リストで初期化できますB
。
A::A( A* p ) : a(p) {}
B::B() : b(&b) {}
* protected
独自の型のインスタンスまたは独自の型から派生したインスタンスの基本メンバーへのアクセスを許可します。
ここには、実際には 2 つの別個の問題があります。
1 つ目は、行が割り当てを行うだけでなく、基本クラス (正常に動作します) と member を初期化しようとすることb
です。b
メンバーを作成するには、それを構築する必要があり、メンバーとしてコンストラクターにアクセスする必要がpublic
ありますが、それはありません。
次に、割り当ても非パブリックメンバーにアクセスできません。これは、タイプではなくタイプであるb
ためです。B
A
これは、オブジェクト (または子)を介してprotected
のみ の一部にアクセスできることを意味することに注意してください。A
B
この場合、あなたの本当の問題を教えてください。解決のお手伝いをいたします。同型からの継承・合成はデザイン臭がする。
私がテストしたすべてのコンパイラーはいくつかのことについて不平を言っていました。特に、代入ステートメントが削除されたとしても、保護されたコンストラクターは問題になります。
protected
派生したタイプのインスタンスのメンバーにアクセスすることはできません。この問題は、11.4p1の例で明らかにされています。
class B {
protected:
int i;
static int j;
};
class D1 : public B {
};
class D2 : public B {
void mem(B*, D1*);
};
void D2::mem(B* pb, D1* p1) {
pb->i = 1; // ill-formed
p1->i = 2; // ill-formed
// ...
}