为什么不是 observer_ptr
move 操作后归零?
它在默认构造中被正确设置为 nullptr
,这确实有意义(并防止指向垃圾)。
相应地,当 std::move()
开始时,它应该被清零,就像 std::string
、std::vector
等
这将使它成为多个上下文中的一个很好的候选者,在这些上下文中,原始指针是有意义的,并且自动在具有原始指针数据成员的类上生成 move 操作,例如 this case .
编辑
正如@JonathanWakely 在评论中指出的(与 aforementioned question 相关):
if
observer_ptr
was null after a move it can be used to implement the Rule of Zero for types that have a pointer member. It's a very useful feature.
最佳答案
一开始似乎很多人都忽略了这个想法的要点和实用性。
考虑:
template<typename Mutex>
class unique_lock
{
Mutex* pm;
public:
unique_lock() : pm() { }
unique_lock(Mutex& m) : pm(&m) { }
~unique_lock() { if (pm) pm->unlock(); }
unique_lock(unique_lock&& ul) : pm(ul.pm) { ul.pm = nullptr; }
unique_lock& operator=(unique_lock&& ul)
{
unique_lock(std::move(ul)).swap(*this);
return *this;
}
void swap(unique_lock& ul) { std::swap(pm, ul.pm); }
};
使用默认构造时为空且 move 后为空的“哑”智能指针,您可以默认三个特殊成员函数,因此它变为:
template<typename Mutex>
class unique_lock
{
tidy_ptr<Mutex> pm;
public:
unique_lock() = default; // 1
unique_lock(Mutex& m) : pm(&m) { }
~unique_lock() { if (pm) pm->unlock(); }
unique_lock(unique_lock&& ul) = default; // 2
unique_lock& operator=(unique_lock&& ul) = default; // 3
void swap(unique_lock& ul) { std::swap(pm, ul.pm); }
};
这就是为什么有一个愚蠢的、非拥有的、 move 后为空的智能指针很有用,比如tidy_ptr
。
但是 observer_ptr
只是默认构造时为 null,所以如果它被标准化,它对于声明一个采用非拥有指针的函数很有用,但它不会有用对于像上面这样的类,所以我仍然需要另一个 非拥有哑指针类型。拥有两个非拥有的哑智能指针类型似乎比没有的更糟糕!
关于c++ - 为什么 observer_ptr 在 move 后不归零?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22310878/