2016-09-30 8 views
1

に導か保護された構造体のためにアクセスできない私はエラー:関数は、C++

struct A { void ohai() {} }; 

struct B: protected A {}; 

struct C: private A { friend int main();}; 

struct D: B { void test() { ohai();} }; 

struct E: C { void test() { ohai();} }; 

int main() { 
    A().ohai(); 
    B().ohai(); 
    C().ohai(); 
    D().ohai();  
    return 0; 
} 

を持っている。しかし、私はこれらのエラーを理解していない

error: ‘void A::ohai()’ is inaccessible 
struct A { void ohai() {} }; 
      ^
main.cpp:20:11: error: within this context 
    B().ohai(); 
    ^
main.cpp:8:17: error: ‘void A::ohai()’ is inaccessible 
struct A { void ohai() {} }; 
      ^
main.cpp:22:11: error: within this context 
    D().ohai(); 

エラーが発生します。 BAから継承されているため、Ohaiにアクセスできませんか?継承をpublicに変更したときにエラーが発生しませんでした

編集:Difference between private, public, and protected inheritance私の質問には答えません。これは、あなたがAがプライベートであることを宣言しているされているので

+3

「B」はしません。 'B'インスタンスから' ohai'を呼び出すことはできません。 – NathanOliver

+1

これは重複していますが、なぜOPにはっきりしないのか理解できます。 コード内の誤解は、継承を保護しているので、WITHIN Bにアクセス可能ですが、外部からはアクセスできません。 つまり、 "B()。ohai()"という行は今は保護された関数をpublicと呼びません。 – Bilkokuya

答えて

0

そのリンクによると、Bohaiを継承する必要があり、保護継承によると:

Struct C : private A{} 

これは、構造体のすべてに対して完全にプライベートなので、アクセスできなくなり受け入れます

+0

Nope。私はコードからこの行を削除して再コンパイルしましたが、 'B()。ohai()'でエラーが表示されます。 – user5739619

0

ファンクションは、保護された継承のため、クラスBおよびクラスBからアクセスできます。このため、D::test()ohaiにアクセスできます。

しかし、main()クラスBの範囲またはBから派生したクラスではないので、main()B().ohai()を呼び出すことが許可されていません。

アクセスチェックの重要な要素は、呼び出し元のオブジェクトではなく、呼び出し元の関数です。

1

privateprotected、およびprivateについてのキーは、クラスとその子孫は、クラスは、クラス外部のコードが、それが何かをサブクラス化されているかどうかを理解しているかどうかに対して、何かをサブクラス化していることを理解しているかどうか理解しています。 BサブクラスprotectedA

struct A { 
    void ohai() {}; 
}; 

たちはクラスAで始まる言います。つまり、Bとその継承者はBAの型であることを理解しています。 public

struct B : protected A { 
    void foo() { 
     A *a = this; 
    } 
}; 

CサブクラスB:確かに、どのようにthisA *に変換可能であるfoo方法、内に注意してください。 Aのタイプ(それはBのタイプであることがわかっており、BはタイプAであることがわかっているため)を知っていることに注意してください。公に最後に

struct C : public B { 
    void bar() { 
     A *a = this; 
    } 
}; 

DサブクラスA::私たちは再びそのbar方法と見ることができ、今まで

struct D : public A { 
}; 

を、私たちは、物事は、クラスの内部から見てどのように考えられてきました。さて、彼らが外でどのように見えるかを見てみましょう。

は、我々が継続言う:

int main() { 
    A *p; 

    A a; 
    B b; 
    D d; 

すると、当然のことながら、p&aを指すことができます。

p = &a; 

DのでサブクラスはA公に、それはまた、&dを指すことができます。

p = &d; 

しかし、Bサブクラスprotectedly Aいるので、それはそれのサブクラスであることを知りません。次の行は、コンパイルに失敗します。

p = &b; 
} 

をそれゆえ、あなたのエラーにつながる - それはそれのサブクラスであることを知らないので、それはohaiメソッドを持っていることを、側面から、知りません。

0

outisdeからプライベートで保護されたデータや機能に直接アクセスすることはできません。そうするには、公共の範囲でゲッターを持つ必要があります。

Bにはohai()がありますが、保護されたスコープの下にあるので、Bのオブジェクトはohai()にアクセスできません。 (保護されたプライベートは外部からはアクセスできないが、公開のみ)。

したがって、B()。ohai()を記述するとコンパイル時にエラーが発生します。

A():ohai()は、オハイがpublic-scopedであるため、ohai()にアクセスできます。デフォルトではprivateであるクラスとは異なり、メンバーはパブリックにアクセスできます。

C:A()(public、protected、private)のすべてのメンバーが構造体Cのプライベートスコープになりますので、そのうちの1つにアクセスしようとするとエラーが発生します。プライベートデータにアクセスする。しかしmain()はCの友人として宣言されているので、private、protected、publicのすべてのメンバーにアクセスできます。 (フレンド関数は、それらが友人に宣言されているすべてのメンバーへのフルアクセスを持っている)など

friend ostream& operator << (ostream&, myClass &rhs); // this function can access all members of myClass 

D:Bから公に継承するので、プライベートEXCEPT Bのすべてのメンバーがプライベートメンバーが継承されていない覚えている(Dになります)、BはAから保護されているので、Bはohai()に直接アクセスすることはできません。したがって、Bはohai()が保護されているため、ohai()にアクセスできません。

あなたが書いた場合:

D().test();// it's ok because test() in D is public and test() is a member of D so it can access ohai(); 

は、E:EはCが、プライベートですべてにアクセスできるようにCから公に継承し、Cは、これらすべてのメンバーように、CでプライベートになりますAのようにすべてのメンバーからの個人継承しますAから継承したCでは継承されません。したがって、EはCで個人的に継承されるため、ohai()にアクセスできません。

関連する問題