我目前陷入了一个非常具体的问题。我有一个map
结构,如:
std::map<int, MyStruct> myMap;
typedef struct
{
long a;
int b;
MyObject* object;
} MyStruct;
结构创建object
始终设置为nullptr
:
void createNewStruct(int id)
{
MyStruct newStruct{2L, 1, nullptr}; // create with no object
myMap.insert(std::pair(id, newStruct)); // store in map
}
我这样做是因为map
中可能有数以千计的结构,但只有少数可能需要一个本身非常大的实际“对象”。
object
本身的生命周期有限,如果当前未显示,则显示,如果当前显示,则不显示。如果达到对象生命周期的结束,则调用停止(this):
void doShow(int id)
{
if(myMap[id].object == nullptr)
{
MyObject* newObject = new MyObject();
connect(object, SIGNAL(stopped(MyObject*), this, (objectStopped(MyObject*)); // create callback to delete object later
myMap[id].object = newObject;
// do something with object
}
}
现在如果停止(this)被调用,我会尝试清理:
void objectStopped(MyObject* object)
{
// do something with object
delete object;
object = nullptr; //????
}
但显然这不符合预期,因为对nullptr
的检查不会再次成真。
所以我想要实现的目标是:我有一个map
有很多结构,但这些结构中只有少数需要object
。如何正确创建和删除此对象?
答案 0 :(得分:1)
我认为实现这一目标的最佳方法是向MyStruct
提供MyObject
所有权,而不使用外部函数来管理该分配。
如果你这样做,你的设计一般会有所改善。
例如,您可以向MyStruct
提供一些函数来管理MyObject
结构的创建:createObject()
创建一个,或destroyObject()
来销毁它,一个函数检查对象是否存在,并且您可以向MyStruct
提供他自己的doShow()
成员函数,这样您的外部doShow(int id)
函数就可以获得正确的MyStruct
#39; ID&#39;然后再打电话给MyStruct::doShow()
。
当你销毁一个MyStruct
对象时,它也会自动释放它的MyObject
(如果有的话),而不用担心它会回调,信号/插槽机制等。
所以,最重要的是:我只是让MyStruct
对象更智能,并为其提供MyObject
类的完整所有权。我相信这会改善整体设计。
答案 1 :(得分:1)
如果你有一个C ++ 11编译器(你应该),你可以使用id
:
connect(object,
SIGNAL(stopped(MyObject*),
this,
[]() { delete myMap[id]; myMap[id] = nullptr; });