25

friend特定の名前空間内で定義されたすべての関数をクラスで作成する方法があるかどうか疑問に思っていましたか?

特に、次のようなクラスがあります。

class C {
    private:
        // ...
    public:
        // ...

        friend C* B::f1(C*);
        friend C* B::f2(C*);
        friend C* B::f3(C*);
        friend C* B::f4(C*);
        friend C* B::f5(C*);
};

および名前空間Bは次のとおりです。

namespace B {
    C* f1(C* x);
    C* f2(C* x);
    C* f3(C* x);
    C* f4(C* x);
    C* f5(C* x);
};

Bここで、名前空間の 5 つの関数すべてをクラスとフレンドにするために、クラス定義に 5 行を記述することは避け、名前空間内で定義されたすべての関数がクラスとフレンドであること (つまり、そのプライベートにアクセスできること)Cをコンパイラに伝えるだけにしたいと思います。メンバー)。BC

私が推測する簡単な修正は、名前空間をクラスに変更し、関数をその静的メンバーとして定義してから、クラスを classBのフレンドとして宣言することCです。しかし、好奇心から、名前空間でもそのようなことが可能かどうか疑問に思っていましたか?

前もって感謝します。

4

2 に答える 2

24

いいえ、名前空間と友達になることはできません。名前空間はどこにでも拡張できるため、少なくとも「セキュリティ違反」になります。そのため、誰でも名前空間に任意の関数を追加して、クラスの非公開データにアクセスできます。

あなたが得ることができる最も近いものは、あなたが提案する解決策であり、それらの関数をクラスの静的メンバーにし、クラスと仲良くします。Cしかし、もう一度言いますが、最初に元のクラス (コード内)の静的メンバーにしないのはなぜですか?

余談ですが、コード内で非常に多くのフレンド関数が必要になった場合、設計についてもう一度考え直すのは難しいでしょう。私は何か間違ったことをしている兆候としてそれを受け取ります.

于 2013-12-30T11:17:03.363 に答える
6

名前空間をクラスに昇格させると、一度に多くの関数と友達になることができます。他にも(多くの)欠点がありますが、実際には(他の理由で)クラスBが必要になる場合があります。

class C {
    private:
        // ...
    public:
        // ...

    friend struct B_domain;
};

struct B_domain {
    static C* f1(C* x);
    static C* f2(C* x);
    static C* f3(C* x);
    static C* f4(C* x);
    static C* f5(C* x);
};
于 2017-04-26T02:19:15.533 に答える