问题摘要:
为类的不同实例保留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());
}
如何正确完成?
答案 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>
转换为SharedDevicePtr
或std::map<type,SharedDevicePtr>
转换为SharedDeviceMap
等等......