この質問は長いので、ご容赦ください。
私は、メモリ管理、共有ポインター、およびマップに関するジレンマを解決しようとしています。私は私のアーキテクチャについてフィードバックを得たかっただけです。
次の例は、擬似コードで行われます。
私はリスナークラスを持っています:
class MyListener {
friend class Command;
public:
MyListener() {}
virtual ~MyListener() {}
void handleUpdate() {
std::cout << "Update Handled" << std::endl;
}
};
これは、オブジェクトの更新が呼び出されるたびに呼び出されます。プロセス間通信フレームワークに OpenDDS というミドルウェアを使用しています。
DDS オブジェクトを継承し、on_data_received() を利用する Command クラスがあります。on_data_received() が呼び出されたら、上記のクラスから handleUpdate() メソッドを呼び出したいと思います。
class Command {
public:
/*standard constructor destructor here*/
void on_data_received() {
m_listener->handleUpdate();
}
void write();
private:
MyListener *m_listener;
};
ここに問題があります。これを管理するクラスはシングルトンであり、publishとsubscribeの 2 つのメソッドを使用して、DDS メッセージを発行するか、DDS メッセージを購読します。subscribeメソッドは、キー値と生のポインターを受け取ります。
シングルトンは、
std::map<std::string name, Command>
CommandクラスにはMyListenerクラスが含まれています。
これを破る疑似コードのスニペットを次に示します。
class TaterTotListener : public MyListener {
void handleCommand() {
std::cout << "Tater tot found" << std::endl;
}
};
int main() {
// make a new smart pointer to the listener
boost::shared_ptr<TaterTotListener> ttl(new TaterTotListener);
// tell the singleton we want to publish an object called "TaterTot"
CommandManager::instance()->publish("TaterTot");
// tell the singleton we want to subscribe to an object called tater tot
CommandManager::isntance()->subscribe("TaterTot", ttl.get());
// processing goes here
// deallocation
}
割り当てが解除されると、ブーストは共有ポインターの所有権を削除します。CommandManager は「TaterTot」という名前のすべてのオブジェクトを削除して「クリーンアップ」を試みますが、boost::shared_ptr はすでに自身をクリーンアップしているため、二重の空きメモリ破損がスローされます。CommandManager シングルトンは常に最後にクリーンアップされるため、生のポインターを宣言して subscribe メソッドに渡すと、同じ動作になります。
そこに何かアイデアはありますか?明白で直感的な何かを見逃していませんか? この場合の共有ポインタの使用法を誤解していますか?
どんな助けでも大歓迎です。ビールを買います。