我正在学习如何使用std::unique_ptr
指针。
我的代码:
#include <iostream>
#include <memory>
class object{
public:
void say(){
std::cout<<"hi";
}
};
int main(){
std::unique_ptr<object> p =
std::unique_ptr<object>(new object);
p->say();
}
我的问题是:
我正确使用std::unique_ptr
吗?
如何删除或删除此(p
)指针,以便没有内存使用或泄漏?
答案 0 :(得分:7)
std::unique_ptr<object> p = std::unique_ptr<object>(new object);
这很好,但你可以这样简化:
std::unique_ptr<object> p { new object{} };
或者在C ++ 14中这样:
auto p = std::make_unique<object>();
您不需要delete
std::unique_ptr
,这就是重点。当p
超出范围时(在main
的末尾),指针对象将自动delete
。
也就是说,在这个例子中没有必要使用动态分配。您应该只使用自动变量:
int main(){
object p{};
p.say();
}
一个好的经验法则是尽可能使用自动存储持续时间,并在必要时使用动态存储持续时间。
std::make_unique
具有在以下情况下防止泄漏的优势:
process(std::unique_ptr<object>(new object), iMightThrow());
如果先执行new object
,那么iMightThrow
运行并抛出,内存将被泄露。 std::make_unique
防范此事:
process(std::make_unique<object>(), iMightThrow());
现在如果iMightThrow()
抛出,std::unique_ptr
将不会被创建,或者它将被销毁并回收内存。
答案 1 :(得分:2)
std::unique_ptr<object> p(new object);
就足够了
你不必对它做任何事情,在它超出范围后它会摧毁它。
答案 2 :(得分:2)
是的,你正在以正确的方式使用它。但是,如果C ++ 14可用,您可以像这样创建它:
auto p = std::make_uniuqe<object>();
关于删除它。它不需要被删除。这是一般智能指针的想法。当它超出范围时,它将删除它自己分配的内存。
答案 3 :(得分:1)
是的,您没有以错误的方式使用unique_ptr
。 unique_ptr
使用资源获取初始化范例 - 即管理新对象是unique_ptr的责任。
这意味着您不必显式删除指针p
,因为当unique_ptr
超出范围(块的结尾或本例中的函数)时析构函数将设法以正确的方式释放内存而不会导致任何泄漏。
查看以下代码(与unique_ptr
类似):
template<class T>
class ScopedPointer : NonCopiable{
private:
T * pointer;
public:
ScopedPointer( T *p): pointer(p){};
virtual ~ScopedPointer(){
delete pointer;
};
T * operator->() const {return pointer;};
T & operator*() const {return *pointer;};
};
ScopedPointer
析构函数将负责删除原始指针!
答案 4 :(得分:0)
如果你可以使用C ++ 14,你可以有一个简短的手:
auto p = std::make_unique<object>();
这里没有内存泄漏,unique_ptr包装堆分配,当它超出范围时,它会释放资源。您不需要手动释放它,只需将其用作正常变量,当然要小心它。