3

我有一个唯一指针向量。其中,我希望一个不占用其指向对象的所有权。怎么做?

vector<unique_ptr<int>> v;
v.push_back(make_unique<int>(10));

unique_ptr<int> p(new int(20)); // add it to v but keep p take the ownership.

问题来自以下案例。我有一个由 GUI 树小部件表示的树结构数据。父节点通过使用 获取其子节点的所有权vector<unique_ptr<T>>。但有一个例外。我有一个常见的单例数据,并且想将其附加到树中以获取友好的用户界面。存在冲突,因为 sigleton 也取得了所有权。使用 share_ptr 有效,但会牺牲一些性能。

感谢大家的回答、意见和建议。这可能是一个设计缺陷。也许我需要一个用于特殊父节点的新类vector<unique_ptr<T>>(对于其他节点),shared_ptr甚至是一个原始指针(对于单例)来处理异常。

4

3 回答 3

8

你想要一个unique_ptr不拥有它所指向的东西的东西。

这些目标是相互矛盾的。的全部意义unique_ptr在于拥有它管理的资源。

我很难推断出你在这里真正想要的是什么,因为你没有说想要做什么——只你想怎么做。为什么你想要一个unique_ptr不拥有资源的?

也许您真正追求的是 a shared_ptr,以便 a 的多个实例shared_ptr可以共享同一对象的所有权。

再一次,也许你所追求的是 a weak_ptr,它本身并不(完全)“拥有”一个指针,直到它被提升为 a shared_ptr

阅读您的编辑后,我可能会预感您在这里真正想要的是什么。你已经说过你希望你的单例对象真正拥有资源,但你仍然希望你vector有一个智能指针。也许您真正想要的是vector拥有一个不拥有对象本身的智能指针,但如果实际拥有的对象被销毁,它将变得无效或“无效”。

如果是这种情况,那么你的单例应该有 a shared_ptr,并且向量应该是 a vector<weak_ptr>。当您需要通过 实际获取对象时vector,您将调用lock提取一个shared_ptr-- 检查返回自lock以确保weak_ptr没有过期。您也可以通过调用来检查是否shared_ptr已过期而不锁定它expired

于 2013-10-16T14:30:39.143 回答
4

你不能用普通unique_ptr<int>的方式来做到这一点——名称是唯一的指针,这是有原因的。

如果你真的很想这样做(但我 99.99% 肯定这只是糟糕设计的症状),你可以使用自定义删除器:

template <class T>
struct WeirdDeleter
{
  bool owning;
  explicit WeirdDeleter(bool owning = true) : owning(owning) {}
  void operator() (const T *p) const {
    if (owning) delete p;
  }
};


//Usage:

vector<unique_ptr<int, WeirdDeleter<int>>> v;
unqiue_ptr<int, WeirdDeleter<int>> p(new int(10));
v.push_back(std::move(p));

int *q = new int(20);
v.push_back(unique_ptr<int, WeirdDeleter<int>>(q, WeirdDeleter(false));

(我不知道make_unique关于删除器的建议接口,所以我没有使用它;它仍然可以使用)。

重复一遍,我认为这样做是个坏主意(tm),但如果你真的想这样做,这应该是方式。

于 2013-10-16T14:36:38.650 回答
3

unique_ptr是针对它具有独占所有权的确切用例。所以你不能用它来指向某些东西而不是取得所有权。

解决方法很简单:shared_ptr改用。它没有独占所有权,相反,它指向同一个对象的所有实例都将共享所有权;只有当最后一个超出范围时,该对象才会被删除。

如果您想要一个不干扰所有权的指针,请查看weak_ptr.

于 2013-10-16T14:29:17.133 回答