2

Foo と Bar の 2 つのクラスがあり、Foo を変更せずに Foo を Bar と友達にしたいとしましょう。これが私の試みです:

class Foo
{
    public:
        Foo(){}

    private:
        void privateFunction(){}
};

template <class friendly, class newFriend>
class friends : public friendly
{
    private:
        friend newFriend;
};

class Bar
{
    public:
        Bar(){}

        void callFriendlyFunction()
        {
            friendlyFoo.privateFunction();
        }

    private:
        friends<Foo, Bar> friendlyFoo;
};

int main(int argc, char* argv[])
{
    Bar bar;

    bar.callFriendlyFunction();

    return 0;
}

プライベート関数を呼び出そうとするとコンパイラ エラーが発生するため、明らかに機能しませんでした。何か案は?

4

3 に答える 3

2

とにかくfriendsアクセスできないため、機能しません(子孫クラスはいずれにせよプライベートフィールドにアクセスできません)。として宣言すると、うまくいきます。privateFunctionprivateprivateFunctionprotected

これは、C++のMixins に関する優れた論文です。(PDFリンク)

于 2010-01-27T10:30:16.533 に答える
1

誰がその友達であるかを宣言できるのは、クラスだけです。外部から注入することはできません。これは単純に理にかなっています。言語で許可されていれば、private メンバーにアクセスすることを意図したすべてのコードがそのトリックを使用できるため、private キーワードをまったく忘れる可能性があります。メソッドは派生テンプレートからアクセスできないため、派生オブジェクトにフレンド関係を追加しても役に立たないことに注意してください。

あなたが試みることができる他のアプローチは、ハッカーであり、移植性がありません ( privateforを変更して同じヘッダーを書き直すことpublicは、多くの状況で機能するように見えますが、いくつかのまれなケースでは失敗します)。

また、クラス テンプレート内で型引数をフレンドとして宣言することはできません。現在の標準では明示的に禁止されていますが、その制限は今後の標準で削除される予定です。

于 2010-01-27T10:35:24.953 に答える
0

あなたはおそらく作るべきです

void privateFunction(){}

保護されています。

おっと、Foo を変更できないことを忘れていました。他に方法はありません。

于 2010-01-27T10:41:34.753 に答える