【发布时间】:2020-08-03 16:36:27
【问题描述】:
在使用 std::unique_ptr 的移动构造函数/赋值时,是否可以假设底层对象没有在内存中重新分配,这样指向它的原始指针仍然有效?
考虑以下程序:
#include <memory>
#include <utility>
#include <iomanip>
#include <iostream>
template <class T>
struct A {
std::unique_ptr<T> data = nullptr;
T *p;
template <class... U>
A(U&&... x) : data{std::make_unique<T>(std::forward<U>(x)...)}, p{data.get()} { }
};
int main()
{
A<int> v{2};
std::cout << std::hex << v.p << std::endl;
A<int> w{std::move(v)};
std::cout << w.p << std::endl;
}
这里w是用A的默认移动构造函数构造的,它调用std::unique_ptr的移动构造函数。
从输出中可以看出,底层分配的int 并未真正在内存中移动,因此默认移动构造函数将w.p 正确初始化为与v.p 相同。
尝试使用其他类型的 T 会得到模拟结果。
是否可以假设std::unique_ptr 的移动构造函数并没有真正移动内存中的对象,因此在上述程序中默认的移动构造函数是正确的?
是语言规定的吗?
或者为了避免悬空指针必须显式添加一个移动构造函数,如下所示?
A(A<T>&& other) : data{std::move(other.data)}, p{data.get()} { }
【问题讨论】:
标签: c++ c++11 unique-ptr move-semantics