[英]How does unique_ptr not destruct/release the memory it points to when it goes out of scope?
If I have a unnamed unique_ptr object, holding a object Foo, why will the object not be deleted when it is added to a vector? 如果我有一个未命名的unique_ptr对象,持有一个对象Foo,为什么该对象在被添加到向量时不会被删除?
Example: 例:
vec.push_back(std::unique_ptr<Foo>(new Foo())));
Why would Foo not be deleted? 为什么不删除Foo? I've attempted to implement this but I can't seem to figure this out, as I delete the object in the destructor.
我试图实现这个,但我似乎无法解决这个问题,因为我删除了析构函数中的对象。
The argument to std::vector::push_back
is a temporary, so it will get passed to push_back
as an rvalue reference . std::vector::push_back
的参数是临时的,因此它将作为右值引用传递给push_back
。 As you can see in the documentation , push_back
has two forms, and the second takes an rvalue reference. 正如您在文档中看到的那样,
push_back
有两种形式,第二种形式采用右值引用。 The unique_ptr
will get moved into the vector, and the temporary that you created for the argument will no longer own the memory. unique_ptr
将被移动到向量中,并且为参数创建的临时将不再拥有内存。
You can't copy an std::unique_ptr
; 你不能复制
std::unique_ptr
; if you tried to, you would get a compile error. 如果你试过,你会得到一个编译错误。 However, moving a unique pointer is perfectly allowable;
但是,移动一个独特的指针是完全允许的; the previous owner no longer owns the memory that it once pointed to.
前一个所有者不再拥有它曾经指向的内存。
In this case, since you're passing a temporary object, the move overload is called: void std::vector<T>::push_back(T&&)
. 在这种情况下,由于您传递的是临时对象,因此调用移动重载:
void std::vector<T>::push_back(T&&)
。 Move semantics allow for nice optimization in situations where expensive copies aren't necessary. 移动语义允许在不需要昂贵副本的情况下进行很好的优化。 Without them,
push_back
would need to make a copy of the unique_ptr
(which actually is not possible with the semantics of unique_ptr
) and you would indeed see the destructor being called. 如果没有他们,
push_back
需要做副本unique_ptr
(这实际上是不可能的语义unique_ptr
),你确实会看到析构函数被调用。 With move semantics, the new unique_ptr
inside the vector is essentially allowed to steal the contents of the temporary, and no copying takes place. 使用移动语义,向量内的新
unique_ptr
基本上允许窃取临时内容,并且不会发生复制。 See here for more explanation of move semantics. 有关移动语义的更多说明,请参见此处 。
This happens because unique_ptr
doesn't have a copy constructor and instead must be moved everywhere. 发生这种情况是因为
unique_ptr
没有复制构造函数,而是必须移动到任何地方。
Here's what happens, in C++11 or 14, ignoring copy/move elision (because the rules changed, we're not allowed to ignore that in C++17): 以下是在C ++ 11或14中忽略复制/移动省略的情况(因为规则发生了变化,我们不允许在C ++ 17中忽略它):
unique_ptr<Foo>
. unique_ptr<Foo>
。 This has the value category of prvalue , a type of rvalue. push_back
method is called. push_back
方法 。 Because the parameter is the temporary created in 1., the second (rvalue reference) overload is called. unique_ptr
's move constructor (the fifth overload on that page), which creates a unique_ptr<Foo>
managing the same Foo
that the temporary in 1 does, and makes the temporary hold nullptr
instead. unique_ptr
的移动构造函数 (该页面上的第五个重载),它创建一个unique_ptr<Foo>
管理与1中的临时值相同的Foo
,并使临时保持nullptr
。 nullptr
, this does nothing in particular. nullptr
,所以没有特别的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.