は、私は、次のクイズの問題があります。継承
#include <iostream>
using namespace std;
struct A
{
void ohai() { cout << "ohai" << endl; }
};
struct C : private A {
friend int main();
};
struct X : C {};
struct Y : private C {};
int main() {
C().ohai() // OK
X().ohai(); // OK
Y().ohai(); // Not OK
}
を事は、クラスCは、個人から継承することです。したがって、Aのすべてのメンバーは、今でもpublicであっても、Cでプライベートになります。 クラスCはmain関数で親しみやすさを宣言します(これはOKで、今は 'main'関数がCのprivateメソッドを呼び出せるようになりました)。 次に、クラスXとクラスYがあります。どちらもCから派生しています。 Xは公にCから派生し、YはCからプライベートに派生します。
私はクラスCのインスタンスを作成し、Aからプライベートに継承された 'ohai'メソッドを呼び出します。mainはCのフレンドですので、これはうまくいきます。 次にクラスXのインスタンスを作成して呼び出します。 'ohai' - これは驚くほど効果的です! しかし、クラスYのインスタンスを作成すると、これはうまくいきません!
私は継承が不可侵ではないことを知っています。これは、クラスXのオブジェクトに対して 'メイン'が 'オハイ'メソッドを呼び出すことを可能にする親和性の継承ではありません。 クラスYのものは、継承のタイプをプライベートに変更してこれを停止するだけで十分であることを確認しますワーキング。
なぜ私はXオブジェクト上で 'ohai'を呼び出すことが大丈夫ですか?継承は関数のレベルを(プライベートからパブリックに)バンプすることはできません。したがって、XがCから継承したとしても、CからのすべてのプライベートメソッドはXでプライベートにしておかなければなりません。親和性は継承できないので、 クラスYはCから個人的に継承しています。これにより、CのすべてのメンバーはXでは非公開になりますが、 'ohai'メソッドはすでにCでプライベートになっています(CはAからプライベートに継承されています)。 anythigを変更すべきではありませんが、どういうわけか(Xと比較して)します。
この問題を理解してもらえますか? よろしくお願いします。 YotKay
にお電話いただきありがとうございます。多分あなたは正しいです。私はあなたの例を試してみました.GCCの例(1)の場合、私は両方のケースで同じエラーが発生しました(エラー: 'A'はアクセス不可能な 'X'のベースです)、友好宣言の有無にかかわらず(Clang、あなたが書いたことによると)。 2番目の例では、あなたが書いたとおり、最初のキャストは上記と同じエラーで失敗し、2番目のキャストは正常に動作します。 – YotKay
@YotKayちょうど "多分"私の答えについてあまり確信してはいけません。何が起こったのか説明できると思う。しかし、私が言ったところでは、標準で特定のフレーズを見つけられませんでした。*この時点まで、私は正しいと確信しています*。与えられた時間より多くの情報を得た他の人があなたに良い答えを与えるかもしれません –
@YotKayアクセスコントロールはメンバー関数の呼び出しを解決した後に来て、メンバ関数呼び出しは暗黙的にベースクラスにキャストされます。 –