为多个类实例维护共享_ptr的静态列表

Maintaining a static list of shared_ptr for multiple class instances

本文关键字:ptr 静态 列表 共享 维护 实例      更新时间:2023-10-16

问题摘要:

在类别的不同实例中保留共享_ptr的静态列表的正确方法是什么,能够从免费函数中获取类实例并管理实例和列表的解构?

目标:

说我有一个设备类,我希望实例化几个实例,每个实例与其他属性类型(例如键盘,鼠标或笔(相对应。然后,我想通过将属性类型传递给static get_instance方法来获取免费功能。

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;
};

我当前如何处理它:

我保留shared_ptr的全局列表

static std::list< std::shared_ptr<Device> > gDeviceInstances;

我在实例化时附加

gDeviceInstances.push_back(std::make_shared<Device>("Pen",Device::Type_t::Pen));

然后从免费函数中检索实例

void freefunction(void){
    std::shared_ptr<Device> m;
    Device::get_instance(m, Device::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;
    }
}

这有效,但我不确定如何管理解构器。SMART_PTR自动删除,损坏列表。而且,如果我手动从列表中删除实例,我也会遇到错误,因为该程序正在尝试删除SMART_PTR。

Device::~Device() {
    std::cout<< "Destructing a device" << std::endl;
    for (auto & s : (gDeviceInstances)){
        if (Type_t (s->getType()) == itsType) {
            gDeviceInstances.remove(s);
        }
    } 

另外,如果我想在类中管理类实例列表,并在类构造函数中附加列表,请说

之类的话
class Device : public std::enable_shared_from_this<Device > {
    public:
    ..
    static std::list< std::shared_ptr<Device > > itsInstances;
    ..
    ..
}; 
std::list< std::shared_ptr<Device > > itsInstances; //Static members must be defined
Device ::Device (std::string const &instance, Type_t type): itsType(type) {
    itsInstances.push_back(shared_from_this());
}

如何正确完成?

edit :删除包装器建议。


首先,使用std::map<type, shared_ptr>代替列表。您可以检查一个项目是否使用map::find(type) != map::end()存在,但是由于默认情况下shared_ptr为null,您可能只能返回 map[type],如果不存在,则共享_ptr将为null。

删除设备只是将一个空的shared_ptr分配给其map插槽:map[type] = shared_ptr<Device>()


另外,请勿返回shared_ptr,返回weak_ptr。虚弱的指针是指可以从下面删除的对象。只需在weak_ptr<Device>.lock()之前检查weak_ptr<Device>.expired(),请访问shared_ptr。


和最后一块:

不要让共享指针删除this

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

typedef是您的朋友。它可以将std::shared_ptr<Device>变成SharedDevicePtrstd::map<type,SharedDevicePtr>变成SharedDeviceMap,等等...