c++ - 我应该如何在工厂类中存储弱指针列表?

标签 c++ c++11 pointers smart-pointers weak-ptr

我的项目中有一个工厂类,返回std::shared_ptr<MyClass> , 如果 Create方法被调用。工厂不是所有者,但它维护一个已创建对象的列表。有时工厂需要迭代仍在使用的已创建对象,或者对它们进行计数。

我使用 std::vector<std::weak_ptr<MyClass>> 实现了这个.迭代看起来像这样:

for (std::weak_ptr<MyClass> wp : weak_list) {
    if (auto sp = wp.lock()) {
        //..
    }
}

Create功能:

std::shared_ptr<MyClass> Create(/* ... */) {
    std::shared_ptr<MyClass> obj = std::make_shared<MyClass>();

    //...

    weak_list.push_back(obj);
    return obj;
}

vector 是像这样的列表的最佳容器吗?也许std::set会更好。

如果我使用 vector 实现它,我必须定期检查列表中的过期指针并将其删除

在工厂类中存储弱指针列表的首选方法是什么?

最佳答案

默认使用 vector 。

Sets不会自行清理过期指针,手动清理过程是一样的。

考虑在迭代之前清除死元素,并迭代弱列表的拷贝(以防迭代改变弱列表)。

如果您需要立即清除悬挂的弱指针,请修改共享指针以在最后一个强引用消失时从弱列表中注销自身。这需要一些与 make shared 有关的工作,包括对齐存储、手动构造和销毁、辅助结构和共享 ptr 的别名构造函数。

template<class T>
struct shared_helper {
  typename std::aligned_storage<sizeof(T),alignof(T)::type data;
  T* get(){ return reinterpret_cast<T*>(&data); }
  bool constructed = false;
  weak_list<T>* list=0;
  std::weak_ptr<T> self;
  ~shared_helper(){
    if (constructed){
      get()->~T();
      constructed=false;
    }
    if (list) list->erase(self);
  }
  template<class...Ts>
  T* emplace(Ts&&...ts){
    T* r = ::new( (void*)&data ) T(std::forward<Ts>(ts)...);
    constructed = true;
    return r;
  }
};
template<class T, class...Args>
std::shared_ptr<T> make_and_register( weak_list<T>& list, Args&&...args ){
  auto r = std::make_shared<shared_helper<T>>();
  if(!r) return {};
  r->emplace( std::forward<Args>(args)... );
  std::shared_ptr<T> ptr( r, r->get() );
  r->self = ptr;
  list.insert(ptr);
  r->list = &list
  return ptr;
}

有点迟钝,未经测试和编译。但在这种情况下,弱列表的集合或无序集合是有意义的,因为我们使用快速查找在最后一个强引用过期时立即清理弱列表。

关于c++ - 我应该如何在工厂类中存储弱指针列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45780961/

相关文章:

c - Malloc 指针数组错误

C++如何使用具有多个通配符的路径查找文件

c++ - 为什么内部类和外部类不能同名?

c++ - 使用 Qt4 的简单菜单栏

c++ - 添加静态 constexpr 成员会改变结构/类的内存映射吗?

c++ - 用 C++ 类模拟指针(包括删除)

c++ - cocos2dx 有时会忽略 setposition()

c++ - 从森林中构建一棵 n 叉树

c++ - 如何使用模板处理不同维度的矩阵?

访问结构指针的正确方法