3

私は次の設定をしています:

foo.h:

class A {
    friend class B;
private:
    A() {}
};

class B {
public:
    void addObject(Object &o); // adds to myMember; A is not exposed!
    void computeResult(Result &r); // uses myMember to compute result
private:
    vector<A> myMember;
};

のオブジェクトは、Aを含むどのプログラムにも公開されませんfoo.h。の付いたベクトルは、その計算アダプターの役割Aを支援するためだけに存在します。BのコンストラクターをプライベートにするAことで、他のコンパイルユニットがそれを使用するのを避けることができると思いましたが、うまくいくようです。ただし、問題は

foo.cpp

void B::computeResult(Result &r) {
    MyCustomStorage<A> storage;
    A *a = storage.allocate(); // error: "A::A() is private"
}

の部分はMyCustomStorage次のようになります。

template <typename T>
class MyCustomStorage {
    T *allocate() {
        ...
        T *ptr = new T[count]; // error: "A::A() is private"
        ...
    }
};

しかしallocate()、メンバー関数から呼び出されるので、これは起こらないと思いました! どうすればこれを解決できますか?

A友達を作ることは、MyCustomStorage非常にスパゲッティ・コディッシュに思えます。ネストAされたプライベート クラスを作成すると、「A はプライベート」であるためB、あらゆる種類のヘルプ クラスが失敗します。foo.cpp

では、これを解決する最もクリーンな方法は何でしょうか?

解決

私は @potatoswatter の 2 番目のソリューションを使用して、次の適切な変更を行いました。

foo.h

class B {
public:
    void addObject(Object &o); // adds to myMember; A is not exposed!
    void computeResult(Result &r); // uses myMember to compute result
private:
    class A {
    private:
        A() {}
    };
    class Helper; // forward declared!
    vector<A> myMember;
};

foo.cpp

class B::Helper {
    int help(A& a) { return 42; } // no problem! Helper is a member of B
}

void B::computeResult(Result &r) {
    MyCustomStorage<A> storage;
    A *a = storage.allocate(); // no problem! A is a member of B
    Helper h;
    h.help(*a); // no problem!
}
4

2 に答える 2