他の回答は、 「is-a」であっても、B
オブジェクトが例の保護された部分にアクセスできないようにする理由を説明しています。もちろん、この問題を解決する最も簡単な方法は、パブリックの一部を作成するか、パブリックにアクセス可能なアクセサメソッドを使用することです。A
B
A
A you want access to
ただし、それが不適切であると判断する場合があります(または、の定義を制御できない場合がありますA
)。A
ここでは、問題を回避するためのいくつかの提案を、破壊のアクセス制御の昇順で示します。これらの回避策はすべて、class A
がコピー構築可能であることを前提としていることに注意してください。
最初のケースでは、コピーコンストラクターを使用しA
てオブジェクトのその部分の初期状態を設定し、B
後で修正します。
class B1 : public A
{
public:
B1() : A(), z(0) {}
B1(const A& item) : A(item), z(1) {
// fix up the A sub-object that was copy constructed
// not quite the way we wanted
x = y;
y = 0;
}
private:
int z;
};
私はそれを信じられないほど混乱させ、おそらく非常にエラーが発生しやすいと思います(A
オブジェクト内のサブオブジェクトB
をコンストラクターに渡されるオブジェクトとは異なるものにしたいA
場合-異常な状況ですが、それが問題で与えられたものです)。ただし、それを実行できるという事実は、以下のより破壊的な例を正当化するものです...
次の例では、アクセスしたいオブジェクトB
の正確な複製を持つ一時オブジェクトを作成します。次に、一時オブジェクトをA
使用して、保護されたアイテムにアクセスできます。B
class B2 : public A
{
public:
B2() : A(), z(0) {}
B2(const A& item) : A(), z(1) {
// create a special-use B2 object that can get to the
// parts of the A object we want access to
B2 tmp( item, internal_use_only);
x = tmp.y; // OK since tmp is of type B
}
private:
int z;
// create a type that only B2 can use as a
// 'marker' to call a special constructor
// whose only purpose in life is to create
// a B object with an exact copy of another
// A sub-object in it
enum internal_use {
internal_use_only
};
B2( const A& item, internal_use marker) : A(item), z(0) {};
};
その解決策は最初の解決策よりも少し混乱が少ないと思いますが、それでも(私の意見では)混乱しています。私たちが望むAオブジェクトの部分にたどり着くためだけにBオブジェクトのろくでなしバージョンを持っているのは奇妙です。
A
必要なアクセスを提供するオブジェクト用の特別なプロキシを作成することで、それについて何かを行うことができます。A
これは「最も破壊的な」回避策であることに注意してください。これは、自分自身のサブクラスでなくても、の保護された部分に到達するためにどのクラスでも実行できるためA
です。クラスの場合、オブジェクトB
の保護された部分に到達することにはある程度の正当性があります。これは-aであり、すでに見てきたように、すでに持っている権限のみを使用してアクセスできるようにする回避策があるため、これは、の場合のこれらの回避策のよりクリーンなバージョンです。A
B
A
class B
class B
class B3 : public A
{
public:
B3() : A(), z(0) {}
B3(const A& item) : A(), z(1) {
// a special proxy for A objects that lets us
// get to the parts of A we're interested in
A_proxy tmp( item);
x = tmp.get_y();
}
private:
int z;
class A_proxy : public A
{
public:
A_proxy( const A& other) : A(other) {};
int get_x() {return x;};
int get_y() {return y;};
};
};