Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从列表C+中删除相关对象+;_C++_List_Oop - Fatal编程技术网

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