2

他のクラスBarで「直接」アクセスする必要があるクラスFooがあります。Bar のメソッド (Foo のフレンド メソッド) が保護されていることを宣言する小さなフレームワークを構築したいと思います。このようにして、Bar の子クラスをいくつか作成することができました。

Gccはそれについて不平を言い、メソッドがパブリックである場合にのみ機能します。

どのようにできるのか?私のコードの例:

class Foo;
class Bar {
    protected:
        float* internal(Foo& f);
};
class Foo {
    private:
        //some data
    public:
        //some methods
        friend float* Bar::internal(Foo& f);
};

GCC メッセージ:

prog.cpp:4:16: error: ‘float* Bar::internal(Foo&)’ is protected
         float* internal(Foo& f);
                ^
prog.cpp:11:43: error: within this context
         friend float* Bar::internal(Foo& f);
                                           ^
4

2 に答える 2

5

クラスの保護された/プライベート メンバーに別のクラスからアクセスできないことは明らかです。これは、protected/private メンバー関数をフレンド登録しようとする場合にも当てはまります。したがって、メソッドをパブリック セクションに入れるかFoo、 のフレンドを作成しない限り、これを行うことはできませんBar

Barクラス全体を のフレンドにすることで、これを行うこともできますFoo。したがって、次のいずれかを行います。

class Bar {
protected:
    friend class Foo; // Foo can now see the internals of Bar
    float* internal(Foo& f);
 };
class Foo {
private:
    //some data
public:
    //some methods
    friend float* Bar::internal(Foo& f);
};

またはこれ:

class Bar {
protected:
    float* internal(Foo& f);
};
class Foo {
private:
    //some data
public:
    //some methods
    friend class Bar; // now Bar::internal has access to internals of Foo
};
于 2014-08-17T14:36:48.607 に答える
2

Fooへの完全なアクセスなしに単一の非公開メソッドによってのみアクセスできるようにしたい場合は、そのタスクBarの中間を作成できます。class

class Foo;
class Bar;
class FooBar {
    friend Foo;
    friend Bar;
    Bar &bar_;
    FooBar (Bar &b) : bar_(b) {}
    float* internal(Foo &f);
};

class Foo {
    private:
        //some data
    public:
        //some methods
        friend float* FooBar::internal(Foo& f);
};

そして今、そのメソッドBarの独自のprotectedバージョンでこの中間クラスを呼び出すことができます。

class Bar {
    friend FooBar;
    // some private data
    protected:
        float* internal(Foo& f) {
            FooBar fb(*this);
            return fb.internal(f);
        }
};
于 2014-08-17T14:42:57.030 に答える