【发布时间】:2017-07-30 14:10:45
【问题描述】:
我不明白为什么这段代码有效:
class Base {
public:
virtual void doStuff() const{}
Base(Base & b) = delete;
Base() {
cout << "Base" << endl;
}
~Base() {
cout << "~Base" << endl;
}
friend ostream& operator<<(ostream& out, const Base& a) {
return out << "me";
}
};
int main(){
unique_ptr<Base> pt = make_unique<Base>();
auto npt = move(pt);
auto &a = *pt;
if (pt == nullptr)
cout << "yes nullptr" << endl;
cout << a << endl;
}
Visual Studio 2015 中的输出是:
Base
yes nullptr
me
~Base
所以它不会崩溃,pt 在被移出后甚至可以使用。
在 coliru 在线编译器中,它在cout << a << endl; 行崩溃。我不明白它为什么不会在auto &a = *pt; 行崩溃,因为此时 pt 等于 nullptr 并且命令 auto &refToNull= nullptr; 是编译错误。
我会感谢您对正在发生的事情进行澄清。
【问题讨论】:
-
未定义的行为是未定义的。
-
您忘记了您的
operator<<函数不是成员函数。这是一个全局非成员函数。尝试调用一个实际的成员函数,或者访问一个成员变量。 -
所以它不会崩溃,
pt被移出后甚至可以使用。 谁说它应该总是崩溃?这是未定义的行为。 -
你的例子归结为
Base& a = *(Base*)nullptr; cout << a;以同样的方式展示UB,我预测会产生同样的结果。unique_ptr或move与它无关 - 它们只是形成了一种非常精细的拼写(Base*)nullptr的方式。
标签: c++ move-semantics unique-ptr