C++ 从列表C+中删除相关对象+;
我有一些代码:C++ 从列表C+中删除相关对象+;,c++,list,oop,C++,List,Oop,我有一些代码: class LowLevelObject { public: void* variable; }; // internal, can't get access, erase, push. just exists somewhere std::list<LowLevelObject*> low_level_objects_list; class HighLevelObject { public: LowLevelObject* lo
class LowLevelObject {
public:
void* variable;
};
// internal, can't get access, erase, push. just exists somewhere
std::list<LowLevelObject*> low_level_objects_list;
class HighLevelObject {
public:
LowLevelObject* low_level_object;
};
// my list of objects
std::list<HighLevelObject*> high_level_objects_list;
// some callback which notifies that LowLevelObject* added to low_level_objects_list.
void CallbackAttachLowLevelObject(LowLevelObject* low_level_object) {
HighLevelObject* high_level_object = new HighLevelObject;
high_level_object->low_level_object = low_level_object;
low_level_object->variable = high_level_object;
high_level_objects_list.push_back(high_level_object);
}
void CallbackDetachLowLevelObject(LowLevelObject* low_level_object) {
// how to delete my HighLevelObject* from high_level_objects_list?
// HighLevelObject* address in field `variable` of LowLevelObject.
}
类低级对象{
公众:
void*变量;
};
//内部,无法访问,擦除,推送。就在某个地方
std::列出低级别对象列表;
类HighLevelObject{
公众:
低级别对象*低级别对象;
};
//我的对象列表
std::列出高级对象列表;
//一些回调,通知LowLevel对象*已添加到low_level对象列表。
void CallbackAttachLowLevelObject(低层对象*低层对象){
HighLevelObject*high_level_object=新的HighLevelObject;
高级对象->低级对象=低级对象;
低级对象->变量=高级对象;
高级对象列表。向后推(高级对象);
}
void callbackdetachLowLevel对象(LowLevel对象*低级别对象){
//如何从高级别对象列表中删除我的高级别对象*?
//HighLevelObject*位于LowLevelObject的“变量”字段中的地址。
}
我在库中定义了低级对象,它包含供用户使用的字段变量
。我将此
varaible
设置为指向我的HighLevelObject
的指针(来自我的代码)。我可以在库中的列表中添加和删除
LowLevelObject
时设置回调。但是如何从对象列表中删除我的
HighLevelObject
当然,我知道我可以迭代整个列表,通过指针按对象查找并删除,但这是一个漫长的过程。列表可能包含很多对象。
提前谢谢 该设置有助于找到一个解决方案,其中将指针转换为迭代器是一个常量时间操作。但这需要对代码进行更改;如果您不小心封装,这些更改可能会非常重要。
boost::intrusive::list
在功能上类似于std::list
,但需要对数据结构进行一些更改。这个选项可能不适合所有人
Intrusive的另一个特性是,有时您不需要显式地将指针转换为迭代器。如果启用自动取消链接,则从列表中实际删除将在析构函数的后台进行。但是,如果您需要在固定时间内获得列表的大小,那么这不是一个好的选择。(问题中没有任何内容表明需要获得列表的大小,因此我将继续使用这种方法。)
如果您有一个对象容器,我可能会让您浏览侵入列表的文档。但是,使用指针可能会使转换变得混乱,因此我将介绍整个设置。设置从以下内容开始
#include <boost/intrusive/list.hpp>
// Shorten the needed boost namespace.
namespace bi = boost::intrusive;
列表的定义如下所示。我们需要指定非常量时间size()
以允许自动取消链接
bi::list<ListEntry, bi::constant_time_size<false>> high_level_objects_list;
接下来,让HighLevelObject
从钩子派生
class HighLevelObject : public bi::list_base_hook< bi::link_mode<bi::auto_unlink> > {
public:
LowLevelObject* low_level_object;
};
“attach”回调几乎恢复到问题中的内容。该函数的一个变化是将对象本身推入列表,而不是指针。这就是为什么切片不是问题;添加到列表中的不是副本,而是对象本身
high_level_objects_list.push_back(*high_level_object); // Intentional indirection!
代码的其余部分可能按原样工作。我们只需要“detach”回调,它也是一个单行程序
void CallbackDetachLowLevelObject(LowLevelObject* low_level_object) {
delete static_cast<HighLevelObject *>(low_level_object->variable);
}
void callbackdetachLowLevel对象(LowLevel对象*低级别对象){
删除静态强制转换(低级对象->变量);
}
该设置有助于找到一个解决方案,其中将指针转换为迭代器是一个常量时间操作。但这需要对代码进行更改;如果您不小心封装,这些更改可能会非常重要。boost::intrusive::list
在功能上类似于std::list
,但需要对数据结构进行一些更改。这个选项可能不适合所有人
Intrusive的另一个特性是,有时您不需要显式地将指针转换为迭代器。如果启用自动取消链接,则从列表中实际删除将在析构函数的后台进行。但是,如果您需要在固定时间内获得列表的大小,那么这不是一个好的选择。(问题中没有任何内容表明需要获得列表的大小,因此我将继续使用这种方法。)
如果您有一个对象容器,我可能会让您浏览侵入列表的文档。但是,使用指针可能会使转换变得混乱,因此我将介绍整个设置。设置从以下内容开始
#include <boost/intrusive/list.hpp>
// Shorten the needed boost namespace.
namespace bi = boost::intrusive;
列表的定义如下所示。我们需要指定非常量时间size()
以允许自动取消链接
bi::list<ListEntry, bi::constant_time_size<false>> high_level_objects_list;
接下来,让HighLevelObject
从钩子派生
class HighLevelObject : public bi::list_base_hook< bi::link_mode<bi::auto_unlink> > {
public:
LowLevelObject* low_level_object;
};
“attach”回调几乎恢复到问题中的内容。该函数的一个变化是将对象本身推入列表,而不是指针。这就是为什么切片不是问题;添加到列表中的不是副本,而是对象本身
high_level_objects_list.push_back(*high_level_object); // Intentional indirection!
代码的其余部分可能按原样工作。我们只需要“detach”回调,它也是一个单行程序
void CallbackDetachLowLevelObject(LowLevelObject* low_level_object) {
delete static_cast<HighLevelObject *>(low_level_object->variable);
}
void callbackdetachLowLevel对象(LowLevel对象*低级别对象){
删除静态强制转换(低级对象->变量);
}
此答案适用于那些不想使用或无法使用Boost.Intrusive的人
只要修改HighLevelObject
是一个选项,就可以告诉对象如何从列表中删除自身。将回调添加到HighLevelObject
并在其析构函数中调用它
#include <functional>
#include <utility>
class HighLevelObject {
public:
LowLevelObject* low_level_object;
// ****** The above is from the question. The below is new. ******
// Have the destructor invoke the callback.
~HighLevelObject() { if ( on_delete ) on_delete(); }
// Provide a way to set the callback.
void set_deleter(std::function<void()> && deleter)
{ on_delete = std::move(deleter); }
private:
// Storage for the callback:
std::function<void()> on_delete;
};
通过这项准备工作,清理工作将在析构函数中进行,这对于RAII来说是合适的。您的“分离”只需启动该过程。一行就够了
void CallbackDetachLowLevelObject(LowLevelObject* low_level_object) {
delete static_cast<ListEntry *>(low_level_object->variable);
}
void CallbackDetachLowLevelObject(LowLevelObject* low_level_object) {
delete static_cast<HighLevelObject *>(low_level_object->variable);
}
void callbackdetachLowLevel对象(LowLevel对象*低级别对象){
删除静态强制转换(低级对象->变量);
}
我正在考虑在
HighLev中存储一个迭代器(特别是上面的iter
)