web-dev-qa-db-ja.com

友情にもかかわらず、アクセスできない基本クラス

このエラーに関しては多くの質問があり、すべての回答はダウンキャストが不可能であることを示唆しているようです。 この答え は、少なくとも私が理解している限り、可能な解決策として友情について言及しています。ただし、次のコード(明確にするために削除された無関係なもの)はコンパイルされません。

class C;

class A {
    friend class C;  // this does not help
};

class B : protected A {
    friend class C;  // this does not help either
};

class C {
    public:
    void foo(A* a) {};
};

B b;
C c;

void bar()
{
    c.foo(&b);  // this produces error: class A is an inaccessible base of B
}

なぜ友情はリファレンスで機能しないのですか?結局のところ、「C」は「B」へのポインタを通じて「A」の保護されたメソッドを完全に呼び出すことができます。

完全なエラーは

prog.cc: In function 'void bar()':
prog.cc:20:13: error: 'A' is an inaccessible base of 'B'
   20 |     c.foo(&b);
11
Maple

保護された継承のため、グローバルスコープではBはAとして表示されません。

クラスB自体、BとクラスCから継承されたクラス(友好関係のため)は、BがAを継承していることを "認識"します。

だからあなたが望むものを達成するために、あなたは呼び出すことができます

c.foo(&b)

cスコープ内で、たとえば、次のようなラッパー関数を使用します(ただし、設計上の決定は正しくありません)。

#include <iostream>
#include <cstdlib>

class C;


class A {
    friend class C;  // this does not help
};

class B : protected A {
    friend class C;  // this does not help either
};

class C {
public:
    void foo() {
        B b;
        foo(&b);  // this call is OK within C-scope
    }
private:
    void foo(A* /*a*/) {
        std::cout << "C::foo(A* a)\n";
    };
};


int main()
{
    std::cout << "Hello, Wandbox!" << std::endl;
    B b;
    C c;
    //c.foo(&b);  // this produces error: class A is an inaccessible base of B
    c.foo();      // this is calling c.foo(A*) internally
}

または live

1
StPiere