私は次の設定をしています:
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!
}