[解決済み] なぜC++は継承された友情を許さないのですか?
質問
なぜ C++ では友情は少なくともオプションとして継承されないのでしょうか? 私は、transitivity と reflexivity が明白な理由で禁止されていることは理解していますが (これは単純な FAQ の引用回答を回避するために言っているだけです)、以下のようなものがないのは残念です。
virtual friend class Foo;
のようなものがないことが私を困惑させています。 この決定の背後にある歴史的背景をご存知の方はいらっしゃいますか? 友情は本当に限られたハックであり、その後、いくつかの不明瞭な立派な用途に道を見つけたのでしょうか?
明確化のために編集します。 次のシナリオについて話しています。 ではなく ここで、Aの子はBのどちらか、またはBとその子の両方に公開されます。 また、フレンド関数のオーバーライドへのアクセスをオプションで許可することなども想像できます。
class A {
int x;
friend class B;
};
class B {
// OK as per friend declaration above.
void foo(A& a, int n) { a.x = n; }
};
class D : public B { /* can't get in A w/o 'friend class D' declaration. */ };
回答受付中です。 として ロキ状態 のように、友好的な基底クラスで保護されたプロキシ関数を作ることによって、その効果を多かれ少なかれシミュレートすることができますので、厳密な が必要です。 はありません。 私は定型的なプロキシ(フレンドベースが事実上そうなる)の必要性が嫌いですが、ほとんどの場合誤用される可能性が高い言語メカニズムよりも望ましいと判断されたのでしょう。 そろそろStroupstrupの C++ の設計と進化
C++ の設計と進化 という本がありますが、この種の質問に対するより良い洞察を得るために、私はここで多くの人が勧めるのを見てきました...
どのように解決するのですか?
なぜなら、私は
Foo
と書くことができ、その友人である
Bar
(というように、信頼関係があります)。
から派生したクラスを書く人は信頼できるのでしょうか?
Bar
?
そうではありません。だから、友情を受け継ぐべきでない。
クラスの内部表現を変更すると、その表現に依存しているすべてのものに変更が必要になります。したがって、クラスのすべてのメンバー、またクラスのすべてのフレンドは、修正を必要とします。
したがって、もし内部表現が
Foo
が変更された場合
Bar
も変更されなければなりません (友情は
Bar
に
Foo
). もし友情が継承されたなら、すべての
Bar
から派生したクラスもまた
Foo
に強く結合しているため、もし
Foo
の内部表現が変更された場合、修正が必要になります。しかし、私は派生型についての知識がありません (別の会社によって開発されているかもしれませんし、そうである必要もありません)。従って、私は
Foo
から派生したすべてのクラスを変更することはできません。
Bar
).
したがって、もし友情が継承されたのであれば、クラスを修正する能力に不注意にも制限を導入することになります。これは、基本的にパブリック API の概念を無にするものであり、望ましいことではありません。
注意:
Bar
にアクセスすることができます。
Foo
にアクセスするには
Bar
にあるメソッドを
Bar
を保護します。そして、その子である
Bar
にアクセスすることができます。
Foo
へのアクセスは、親クラスを経由して呼び出すことで可能です。
これでいいのでしょうか?
class A
{
int x;
friend class B;
};
class B
{
protected:
// Now children of B can access foo
void foo(A& a, int n) { a.x = n; }
};
class D : public B
{
public:
foo(A& a, int n)
{
B::foo(a, n + 5);
}
};
関連
-
[解決済み】C++ - 適切なデフォルトコンストラクタがない [重複]。
-
[解決済み] explicit キーワードの意味は?
-
[解決済み] using namespace std;」はなぜバッドプラクティスだと言われるのですか?
-
[解決済み] 要素ごとの加算は、結合ループよりも分離ループの方がはるかに高速なのはなぜですか?
-
[解決済み] なぜC++はPythonよりもstdinからの行の読み込みが遅いのですか?
-
[解決済み] なぜテンプレートはヘッダーファイルでしか実装できないのですか?
-
[解決済み] なぜ、オブジェクトそのものではなく、ポインタを使用しなければならないのですか?
-
[解決済み] 0.1fを0にすると、なぜ10倍もパフォーマンスが落ちるのですか?
-
[解決済み] なぜList<T>を継承しないのですか?
-
[解決済み] Pythonのクラスはなぜオブジェクトを継承するのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++ 非推奨の文字列定数から「char*」への変換について
-
[解決済み】C-stringを使用すると警告が表示される。"ローカル変数に関連するスタックメモリのアドレスが返される"
-
[解決済み】「corrupted size vs. prev_size」glibc エラーを理解する。
-
[解決済み】テンプレートの引数1が無効です(Code::Blocks Win Vista) - テンプレートは使いません。
-
[解決済み】'cout'は型名ではない
-
[解決済み】エラー:strcpyがこのスコープで宣言されていない
-
[解決済み】エラー:不完全な型へのメンバーアクセス:前方宣言の
-
[解決済み】1つ以上の多重定義されたシンボルが見つかる
-
[解決済み】C++ - 適切なデフォルトコンストラクタがない [重複]。
-
[解決済み】std::cin.getline( ) vs. std::cin