问题总结:
为类的不同实例保留 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());
}
如何正确完成?
最佳答案
编辑:删除包装建议。
首先,使用 std::map<type, shared_ptr>
而不是列表。您可以使用 map::find(type) != map::end()
检查项目是否存在, 但由于 shared_ptr 默认为空,您可能只返回 map[type]
如果它不存在,则 shared_ptr 将为空。
删除设备只是分配一个空的 shared_ptr
到它的map
插槽:map[type] = shared_ptr<Device>()
此外,不要返回 shared_ptr
, 返回 weak_ptr
.弱指针旨在指向可以从其下删除的对象。只需检查 weak_ptr<Device>.expired()
之前 weak_ptr<Device>.lock()
转到 shared_ptr。
最后一 block :
不要让共享指针删除this
.
// specify a delete functor that does nothing, this creates a non-owning shared_ptr
mThisSharedPtr = SharedPtr(this, /*NoDeleteFunc*/ [](DisplayObject*) {});
typedef
是你的 friend 。可以转std::shared_ptr<Device>
进入SharedDevicePtr
或 std::map<type,SharedDevicePtr>
进入SharedDeviceMap
等等……
关于c++ - 为多个类实例维护 shared_ptr 的静态列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44265055/