s のセットとs のリストをBagOfThings
格納するオブジェクト があります。これらは、が追加されたとき、または追加された から削除されたときを知りたいと考えています。このような:Thing
BagOfThingsListener
Thing
BagOfThings
class Thing;
class BagOfThings;
class BagOfThingsListener {
public:
virtual ~BagOfThingsListener() {}
virtual void thingAdded(std::shared_ptr<BagOfThings> bag, std::shared_ptr<Thing> thing)=0;
virtual void thingRemoved(std::shared_ptr<BagOfThings> bag, std::shared_ptr<Thing> thing)=0;
};
class BagOfThings: public enable_shared_from_this<BagOfThings> {
private:
std::set<std::shared_ptr<Thing>> things;
std::list<std::shared_ptr<BagOfThingsListener>> listeners;
private:
BagOfThings() {}
public:
static std::shared_ptr<BagOfThings> create() {
return std::shared_ptr<BagOfThings>(new BagOfThings());
}
void addThing(std::shared_ptr<Thing> thing) {
things.insert(thing);
for (auto it=begin(listeners); it!=end(listeners); ++it) {
(*it)->thingAdded(shared_from_this(), thing);
}
}
void removeThing(std::shared_ptr<Thing> thing) {
things.erase(thing);
for (auto it=begin(listeners); it!=end(listeners); ++it) {
(*it)->thingRemoved(shared_from_this(), thing);
}
}
~BagOfThings() {
for (auto it=begin(things); it!=end(things);) {
auto currentIt=it++;
auto ¤tThing=*currentIt;
things.erase(currentIt);
for (auto it2=begin(listeners); it2!=end(listeners); ++it2) {
(*it2)->thingRemoved(shared_from_this(), currentThing);
}
}
}
};
shared_from_this()
これは、デストラクタが呼び出されるまでにすべてshared_ptr
の s が破棄されたときに使用できないため、無効なデストラクタを除いて正常に機能します。この場合、私は共有ポインタを使用していますが、デストラクタから this ポインタを配布することはとにかく問題があるように思えます。たとえば、誰かがポインタを保存する可能性があります。thingAdded
しかし、この場合(すべての要素の削除の破棄をリスナーに知らせたい)、呼び出し元へのポインターをリスナーから削除しないと(つまり、 になる) 、明らかに良い方法がわかりませんvoid thingAdded(std::shared_ptr<Thing>)
。
何か案は?