我正在学习新的c ++内容,而我目前正在学习使用智能指针(std::unique_ptr
)。
假设我有std::vector
std::unique_ptr
。在我的代码中的某一点,我需要迭代这个stl向量并挑选出我需要计算的对象。
for (const auto& obj : objectList)
{
if(/*check if this is an object I need*/)
OtherFunc(obj.get());
}
void OtherFun(object* obj)
{
std::vector tempVector.push_back(obj);
}
在OtherFunc中,我将作为参数传入的此对象添加到我保留并进行计算的另一个std::vector
(表示为otherVector)。我不希望OtherFunc
拥有对象的所有权。我只需要保留它们,所以我不必每帧传递对象。
我知道如果智能指针离开作用域(或者在我的情况下,退出程序),它们将自行解除分配,对包含智能指针对象的对象的otherVector会发生什么。我尝试在cplusplus.com查看文档,但我无法得到我的问题的答案。我是否必须取消分配我保存在otherVector中的所有对象?或者由于对象最初是智能指针,我可以假设otherVector中的所有指针也将变为null(因此,不会导致内存泄漏)。
答案 0 :(得分:8)
Documentation for get()
将声明它只返回一个指向托管资源的非所有者指针,而不是release()
,它实际上将所有权转移到返回的指针。
这足以回答你的问题不应该清理指针。但是,还有其他一些需要注意的问题。
首先,您必须对生命周期持谨慎态度。管理资源仍然是智能指针的工作。如果智能指针清理,则原始指针将悬空。确保智能指针超过原始指针。如果你不能这样做,你应该使用shared_ptr
,这可以确保只有在完成所有关联的智能指针后才清理资源。
现在有两种方法可以使用shared_ptr
执行此任务。两者都需要将原始向量中的智能指针类型更改为shared_ptr
。在前言中,假设您正在使用此指针并将其存储以供以后使用。当它被使用时,原始矢量可能会消失,其中的智能指针随之消失。我还假设您需要一个原始指针来执行您对资源执行的操作。也许您需要将它赋予C函数。
直接使用。如果您希望资源至少与OtherFun
使用它所需的资源一样长,这是很好的。 OtherFun
将采用shared_ptr
,现在可以通过直接传递vector元素而不使用get
来创建get
。
shared_ptr
会导致错误,因为shared_ptr
需要从另一个OtherFun
构建,以便对资源进行适当的引用计数。 shared_ptr
将shared_ptr
存储在任何需要的地方,并且存储的指针确保资源在原始向量时不会死亡。
当有时间访问资源时,您可以从shared_ptr
获取所需的原始指针,并确保本地weak_ptr
比原始指针的使用寿命更长,这更容易而不是确保它比矢量元素更长。
存储OtherFun
。如果您希望原始向量是唯一负责资源的向量,但是需要能够检查资源是否仍然有效并且如果是,则使用它。 weak_ptr
会在任何需要的地方存储shared_ptr
。如果原始矢量死亡,资源也会。
当需要在其他地方使用资源时,使用weak_ptr
从lock
获取shared_ptr
(可能为空shared_ptr
}或weak_ptr
从shared_ptr
转换构造函数(抛出可能的异常)。您可以适当地检查资源是否仍然存在,get()
确保它将保留在那里,直到您完成为止。此时,您可以继续选项1并获取所需的原始指针。
除此之外,您必须小心所有权。来自void OtherFun(object* obj)
{
std::unique_ptr<object> p(obj);
}
的原始指针绝不能变成任何类型的所有者。例如,以下是错误,将导致指针的双重删除:
*obj
此处,您已p
对unique_ptr
拥有独特的所有权,即使您拨打的get()
*obj
仍然拥有shared_ptr::get()
。这类似于前面提到的shared_ptr
陷阱,您最终会有两个未关联的get()
来管理相同的资源。
release()
本质上有些不安全并打破了封装。但是,为了实际使用智能指针,智能指针也是必要的。请注意,您可以陷入陷阱,无论是从获取原始指针的生命周期,还是最终将非拥有的原始指针转换为所有者。这就是res.write("{0}|{1}\n".format(line1.rstrip(), line2.rstrip()))
函数的用途。一般来说,当您不需要智能指针的原始指针以及仅将原始指针视为非所有者时,您会更加安全。
答案 1 :(得分:2)
您可以将另一个向量声明为std::vector<object*>
。它将保存对象指针,但不会拥有它们,因此在释放自身时不会尝试释放对象。释放原始std::vector<std::unique_ptr<object>>
时将释放对象。只需确保原始矢量比其他矢量更长。
答案 2 :(得分:2)
您可以使用指向std::unique_ptr
内部的指针来“偷看”,但这对于智能指针是不可见的。如果唯一指针超出范围并删除其对象,则对其保持对象的任何普通指针都将变为无效。只要在唯一指针删除了对象后就不会使用常规指针,那么你是安全的,但是没有给出保护!
如果您需要多个指向具有不同生命周期的对象的指针,请考虑std::shared_ptr
。