一段代码片段:
std::unique_ptr<SDL_Renderer, decltype(&SDL_DestroyRenderer)>
cGraphics::Create_Renderer()
{
SDL_Renderer* temprenderer = SDL_CreateRenderer(m_Window.get(), -1, 0);
SDL_SetRenderDrawColor(temprenderer, 255, 255, 255, 0xff);
return std::unique_ptr<SDL_Renderer,
decltype(&SDL_DestroyRenderer)>(temprenderer,
SDL_DestroyRenderer);
}
我所知道的:
temprenderer
当然超出范围时会被销毁; std::unique_ptr
; std::unique_ptr
不允许复制,但可以按值返回; std::unique_ptr
超出范围时也会被销毁; 我的问题:
为什么原始指针的破坏对临时唯一指针的副本没有影响,而临时唯一指针的副本本身(临时唯一指针)是用原始指针初始化的?换句话说,在防止信息丢失的唯一指针内部发生了什么?
我的假设是,唯一指针也包含一个原始指针(例如.get()
),当它由temprenderer
启动时,它将temprenderer
的值复制到原始指针中,当唯一指针超出范围时,该信息将再次被复制。
好的,经过深思熟虑,这听起来很明显,但是如果有人可以确认这一点,我将不胜感激。我也发现了这一点:
unique_ptr明确禁止复制其包含的指针(正常分配时会发生这种情况)
所以当我们返回unique_ptr
时也许还会发生一些额外的事情吗?
答案 0 :(得分:1)
当我们返回临时unique_ptr
时,编译器实际上通过调用move构造函数来“移动”资源。一旦移动了资源,原始临时unique_ptr
就超出范围并被销毁。即使unique_ptr
是左值,但即使编译器发现函数返回后它仍然会超出范围(不再需要),它也会执行 copy Elision 并选择返回的move构造函数。
为什么原始指针的破坏对临时唯一指针的副本没有影响,而临时唯一指针的副本本身(临时唯一指针)是用原始指针初始化的?换句话说,在防止信息丢失的唯一指针内部发生了什么?
因为不是要破坏的内容,而是保存地址的变量。并且unique_ptr
一旦拥有内容的地址,为什么仍然重要呢?
我的假设是,唯一指针还包含一个原始指针(例如.get()),当它由temprenderer启动时,它将temprenderer的值复制到原始指针上,并且当唯一指针超出范围。
用unique_ptr
初始化temprenderer
时,它只是将temprenderer
指向的地址复制到其自己的成员变量中。当控件超出范围时,该信息将不复制,而是移动(所有权转移)。
答案 1 :(得分:1)
unique_ptr明确禁止复制其包含的指针(如 通常会发生这种情况)
template<class U, class E>
unique_ptr(unique_ptr<U, E>&& u) noexcept;
U
是MoveConstructible和MoveAssignable的,但是按照unique.ptr/4 不是 CopyConstructible 或 CopyAssignable 的。>
因此,它可以防止复制。相反,它会转让所有权。