为多个类实例维护shared_ptr的静态列表

时间:2017-05-30 14:29:28

标签: c++

问题摘要:

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

目的:

假设我有一个设备类,我希望实例化一些实例,每个实例对应一个不同的属性类型(例如键盘,鼠标或笔)。然后,我希望有一个自由函数通过将属性类型传递给静态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());
}

如何正确完成?

1 个答案:

答案 0 :(得分:0)

修改:删除了包装建议。

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

删除设备只是将空shared_ptr分配到其map广告位:map[type] = shared_ptr<Device>()

此外,请勿返回shared_ptr,请返回weak_ptr。弱指针旨在指向可以从它们下面删除的对象。只需在weak_ptr<Device>.expired()到shared_ptr之前检查weak_ptr<Device>.lock()

最后一块:

不要让共享指针删除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等等......