A、B、Cの3つのクラスがある場合、AとBは友達です(双方向)。また、B と C はフレンド (双方向) です。A には B へのポインターがあり、B には C へのポインターがあります。A がポインターを介して C のプライベート データにアクセスできないのはなぜですか?
明確にするために、これは純粋に理論的な C++ 言語の質問であり、設計に関するアドバイスの質問ではありません。
ジョンは私の友人で、いつでも私のワイヤレス接続を使用できます (私は彼を信頼しています)。
ジョンの友人であるティムは浪費家であり、ジョンは私の友人ですが、私はティムを友人として含めていないため、彼に私のワイヤレス接続を使用させません。
また、ジョンの子供たちはフーリガンの集まりなので、私は彼らを信頼していません。
私たちの子供たちはワイヤレスに直接アクセスすることはできませんが、私たちを経由すればアクセスできます。したがって、John の子供たちは、John を介してアクセスすれば、私のワイヤレスにアクセスできます (つまり、John によって監視および保護されています)。
ジョンは政府の仕事をしているため、残念ながら、特にワイヤレスに関しては、誰も信用することはできません。
これにより、実際のアクセスがない場合でも、別のオブジェクトのプライベート メンバーにアクセスできるコピー コンストラクターなどを使用できます。
したがって、私はすべてのクローンと自動的に友達になります:-)それらは私の他のインスタンスにすぎないためです.
C++ のフレンドシップは推移的ではありません。
(A is friend of B) and (B is friend of C) does not mean (A is friend of C)
また、友情は対称的ではありません。
(A is friend of B) does not mean (B is friend of A)
A 内から C のプライベートなものにアクセスできるようにするには、A が C のフレンドであることを明示的に述べる必要があります。セッターとゲッターをクラスに追加すると、公開することを意図していない情報が公開される場合は、フレンドを検討する必要があります。あなたのデザインが間違っていることを発見してください (友人を使うことは有効です。それは悪いデザインの兆候ではありません)。インターフェイスを破壊することなくセッターとゲッターを追加できる場合は、他のクラスの友達を作ることは避けるべきです。ネストされたクラスは、常にネストされたクラスのフレンドであることに注意してください。したがって、ネストされたクラスは、ネストされたクラスのプライベートを見ることができます。
返信を待っているときに、この記事を見つけました。それは私の質問にかなりよく答えます: C++ のフレンド スコープ
C++ では、友情は推移的なプロパティではないためです。実際には、システムが複雑になるため、可能な限り避ける必要があります。
B がメディエーター クラスで、A と C が管理する必要があるコンポーネントであると想像してください。ボタンがチェックボックスの実装にアクセスする必要があることに本当に意味があると思いますか?
ところで、あなたが尋ねた場合、あなたのタイトルの「階層」がどこにあるのかわかりません。
これはすべてここに要約されています:
What does it mean that "friendship isn't inherited, transitive, or reciprocal"?
-->
これは、フレンド クラスから派生したクラスが自動的にフレンドになることはなく (フレンドの子供を信頼しますか?)、フレンドのフレンドが自動的にフレンドにならないことを意味します (フレンドのフレンドを信頼しますか?)。 、そして別のクラスを「友達」として宣言するクラスは、自動的にそのクラスの友達にはなりません (あなたを友達と呼ぶ人を信頼しますか?)。
から