C++ 为多个类实例维护共享ptr的静态列表

C++ 为多个类实例维护共享ptr的静态列表,c++,C++,问题摘要: 为一个类的不同实例保留一个共享的ptr静态列表,能够从一个自由函数中获取类实例并管理实例和列表的解构,正确的方法是什么 目标: 假设我有一个设备类,我希望实例化两个实例,每个实例对应不同的属性类型(例如键盘、鼠标或笔)。然后,我想让一个自由函数通过将属性类型传递给静态get_实例方法来获取类实例 class Device { public: typedef enum class Type_t { Keyboard = 0, Mouse,

问题摘要:

为一个类的不同实例保留一个共享的ptr静态列表,能够从一个自由函数中获取类实例并管理实例和列表的解构,正确的方法是什么

目标:

假设我有一个设备类,我希望实例化两个实例,每个实例对应不同的属性类型(例如键盘、鼠标或笔)。然后,我想让一个自由函数通过将属性类型传递给静态get_实例方法来获取类实例

class Device {
public:
    typedef enum class Type_t {
        Keyboard = 0,
        Mouse,
        Pen
    };

    Device(std::string const & instance, Type_t type);
    ~ Device();
    Type_t getType() { return itsType;}

    static void get_instance(std::shared_ptr<Device> & inst, Type_t type);
private:
    Type_t itsType;
};
类设备{
公众:
typedef枚举类类型{
键盘=0,
老鼠
笔
};
设备(标准:字符串常量和实例,类型\u t类型);
~Device();
Type_t getType(){return itsType;}
静态void get_实例(std::shared_ptr&inst,Type_t Type);
私人:
类型\其类型;
};
我目前的做法:

我保留共享的全球列表

static std::list< std::shared_ptr<Device> > gDeviceInstances;
static std::listgDeviceInstances;
我在实例化时附加的

gDeviceInstances.push_back(std::make_shared<Device>("Pen",Device::Type_t::Pen));
gDeviceInstances.push_back(std::make_shared(“Pen”,Device::Type_t::Pen));
然后从自由函数中检索实例

void freefunction(void){
    std::shared_ptr<Device> m;
    Device::get_instance(m, Device::Type_t::Pen);
    m->DoSomething();
}
void自由函数(void){
std::共享的ptr m;
设备::get_实例(m,设备::Type_t::Pen);
m->DoSomething();
}
在哪里

void Device::get_instance(std::shared_ptr<Device> & inst, Device::Type_t type) {
    for (auto & s : (gDeviceInstances)){
        if (s->getType() == type) { inst = s;}}
    if (inst == nullptr) {
        std::cout<< "No matching Device Class instance" << std::endl;
    }
}
void Device::get\u实例(std::shared\u ptr&inst,Device::Type\u t Type){
用于(自动和s:(gDeviceInstances)){
如果(s->getType()==type){inst=s;}
如果(inst==nullptr){

std::cout编辑:删除包装建议


首先,使用
std::map
而不是列表。您可以使用
map::find(type)!=map::end()
检查项目是否存在,但由于shared\u ptr默认为null,您可能只需返回
map[type]
,如果它不存在,则shared\u ptr将为null

删除设备只是将一个空的
shared\u ptr
分配给它的
map
插槽:
map[type]=shared\u ptr()


另外,不要返回
shared\u ptr
,返回
weake\u ptr
。弱指针是指可以从它们下面删除的对象。只需在
weake\u ptr.expired()
之前选中
weake\u ptr.lock()
ing到共享\u ptr


最后一段:

不要让共享指针删除此

// specify a delete functor that does nothing, this creates a non-owning shared_ptr
    mThisSharedPtr = SharedPtr(this,   /*NoDeleteFunc*/ [](DisplayObject*) {});


typedef
是你的朋友。它可以将
std::shared\u ptr
变成
SharedDevicePtr
std::map
变成
SharedDeviceMap
,等等。

编辑:删除包装建议


首先,使用
std::map
而不是列表。您可以使用
map::find(type)!=map::end()
检查项目是否存在,但由于shared\u ptr默认为null,您可能只需返回
map[type]
,如果它不存在,则shared\u ptr将为null

删除设备只是将一个空的
shared\u ptr
分配给它的
map
插槽:
map[type]=shared\u ptr()


另外,不要返回
shared\u ptr
,返回
weake\u ptr
。弱指针是指可以从它们下面删除的对象。只需在
weake\u ptr.expired()
之前选中
weake\u ptr.lock()
ing到共享\u ptr


最后一段:

不要让共享指针删除此

// specify a delete functor that does nothing, this creates a non-owning shared_ptr
    mThisSharedPtr = SharedPtr(this,   /*NoDeleteFunc*/ [](DisplayObject*) {});


typedef
是您的朋友。它可以将
std::shared\u ptr
转换为
SharedDevicePtr
std::map
转换为
SharedDeviceMap
,等等。

与您的问题和问题无关,但“转到”默认情况下,您应该使用的容器应该是
std::vector
。如果您有特殊要求,请只使用其他容器中的一个,或者使用容器适配器。@Someprogrammerdude此应用程序中
list
的一点是,您可以在列表中为自己的条目保留一个迭代器,并在恒定的时间内删除自己,而无需任何更改使列表中的任何其他条目无效。也许我误解了,但在我看来,您依赖
设备的析构函数来删除列表中自己的条目。如果是这种情况,您的析构函数将永远不会被调用,因为
共享\u ptr
将始终存在,因此“最后一个”实例的
shared_ptr
永远不会被销毁。你考虑过使用一个列表吗?@FrançoisAndrieux如果需要将迭代器存储到元素,那么这就是我要说的“特殊要求”的一部分。:)拥有
Device::get_instance()有什么意义
接受对
std::shared_ptr
的引用以填充它,而不是仅仅返回
std::shared_ptr
。与您的问题和问题无关,但“转到”默认情况下,您应该使用的容器应该是
std::vector
。如果您有特殊要求,请只使用其他容器中的一个,或者使用容器适配器。@Someprogrammerdude此应用程序中
list
的一点是,您可以在列表中为自己的条目保留一个迭代器,并在恒定的时间内删除自己,而无需任何更改使列表中的任何其他条目无效。也许我误解了,但在我看来,您依赖
设备的析构函数来删除列表中自己的条目。如果是这种情况,您的析构函数将永远不会被调用,因为
共享\u ptr
将始终存在,因此“最后一个”
shared_ptr
实例永远不会被销毁。你考虑过使用一个列表吗?@FrançoisAndrieux如果需要将迭代器存储到元素中,那么这就是我要说的“特殊要求”的一部分。:)拥有
Device::get_instance()
接受对
std::shared_ptr的引用有什么意义
// specify a delete functor that does nothing, this creates a non-owning shared_ptr
    mThisSharedPtr = SharedPtr(this,   /*NoDeleteFunc*/ [](DisplayObject*) {});