我有一个独特的指针向量。其中,我想要一个不占用其尖头物体的所有权。怎么做?
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
甚至是一个原始指针(对于单例)来处理异常。
答案 0 :(得分:8)
您希望unique_ptr
不拥有它指向的内容。
这些目标是相互对立的。 unique_ptr
的重点是拥有它管理的资源。
我很难在此之后推断出你真正 >你是如何尝试的。为什么你想要一个不拥有资源的unique_ptr
?
也许您真正追求的是shared_ptr
,因此shared_ptr
的多个实例可以共享同一对象的所有权。
然而,或许你所追求的是weak_ptr
,它本身不会(完全)“拥有”一个指针,直到它被提升为shared_ptr
。
阅读完你的编辑后,我可能会预感到你在这之后的真实情况。您已经说过,您希望您的单例对象实际拥有该资源,但您仍希望vector
拥有智能指针。也许你真正想到的是vector
有一个智能指针,它不拥有对象本身,但如果实际拥有的对象被破坏,它将变为无效或“无效”。
如果是这种情况,那么您的单身人士应该有一个shared_ptr
,并且该向量应该是vector<weak_ptr>
。当您需要通过vector
实际访问该对象时,您将致电lock
以提取shared_ptr
- 检查lock
的回复以确保{ {1}}尚未过期。您也可以通过调用weak_ptr
来查看shared_ptr
是否已过期而未锁定它。
答案 1 :(得分: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),但如果你真的想这样做,那应该就是这样。
答案 2 :(得分:3)
unique_ptr
用于具有独占所有权的确切用例。所以你不能用它来指向某些东西而不取得所有权。
解决方案很简单:改用shared_ptr
。它没有独占所有权,相反,它指向同一对象的所有实例都将共享所有权;只有当最后一个超出范围时,该对象才会被删除。
如果您想要一个不会影响所有权的指针,请查看weak_ptr
。