我在参考std::unique_ptr
看到下面的注释:
只有非常量
unique_ptr
才能将托管对象的所有权转移到另一个unique_ptr
。由 conststd::unique_ptr
管理的对象的生存期仅限于创建指针的范围。
有没有人可以用例子来解释它?我想不通为什么。
根本无法从const std::unique_ptr
移动,也不能使用其他修改成员函数 - swap
、release
和reset
(这些在逻辑上是非常量限定的,不能在const
实例上调用)。
转让所有权意味着将旧所有者重置为非所有者状态,从而对其进行修改。
const std::unique_ptr
在其生存期内(从其初始化开始)最多管理一个对象。
在std::unique_ptr const&
的情况下,您将无法通过此引用(常量正确性)从引用的(甚至是非常量)std::unique_ptr
转移所有权。
reset
、release
、swap
和移动赋值函数是非常量成员函数,因此不能与std::unique_ptr
类的常量实例一起使用。因此,const std::unique_ptr
无法被修改,并且被迫拥有指针,直到它超出范围。
您可以使用移动赋值或移动构造函数将托管对象的所有权转移到另一个unique_ptr
,例如:
std::unique_ptr<int> p(new int(1));
std::unique_ptr<int> q(std::move(p));
//now q owns the pointer, which is freed when q is destructed
但是,如果p
const
,您将无法执行此操作,并且当p
被销毁时,托管对象将被释放:
const std::unique_ptr<int> p(new int(1));
std::unique_ptr<int> q(std::move(p)); //compilation error
unique_ptr拥有它指向的内存。
void MyFunc()
{
// Creates a unique pointer that points at a Foo object.
std::unique_ptr<Foo> foo = std::make_unique<Foo>();
// ... do some stuff, then return
}
在此示例中,我们创建一个 Foo 对象并将其分配给我们的unique_ptr
.通常,当您在堆上创建某些内容时,您必须使用new
堆中为其分配空间并构造它,delete
销毁它并释放其空间。在这里,一旦您离开创建unique_ptr
的范围(在本例中为函数的结束),unique_ptr
就会处理释放。
只有非常量unique_ptr才能将托管对象的所有权转移到另一个unique_ptr。
这意味着您可以将指针的所有权转移到不同的unique_ptr
,但前提是它没有标记为 const。一次只能有一个unique_ptr
拥有对象。
一种方法是这样的:
std::unique_ptr<Foo> foo1 = std::make_unique<Foo>();
std::unique_ptr<Foo> foo2 = std::move(foo1);
现在,foo1
中的指针已移至 foo2
。 foo1
不再管理该内存,foo2
。
由 const std::unique_ptr 管理的对象的生存期仅限于创建指针的范围。
这意味着,当您的unique_ptr离开作用域时,它会删除它指向的对象。就好像你这样做了:
void MyFunc()
{
Foo* foo = new Foo()
// ... do some stuff, then return
delete foo;
}
好处是现在您不必手动调用 delete,这很好,因为如果您忘记删除它,这是一个潜在的内存泄漏。