我不明白为什么这段代码有效:
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
move 后甚至可以使用。
在 coliru 在线编译器中,它在 cout << a << endl;
行崩溃.我不明白它怎么不会在 auto &a = *pt;
行崩溃, 因为此时 pt 等于 nullptr 并且命令 auto &refToNull= nullptr;
是编译错误。
如果您能澄清发生了什么,我将不胜感激。
最佳答案
首先声明
auto &a = *pt;
是未定义的行为,即未定义。取消引用 nullptr
在 C++ 中不会使您的程序崩溃,它可能会发生所有事情。
您可能期望从您的代码中得到一个 segmentation fault , 但它不会发生,因为您实际上从未访问过对象 a
.
确实,您的 operator<<
拿个Base
对象,但它根本不使用它。
相反,如果您尝试执行以下操作:
friend ostream& operator<<(ostream& out, const Base& a) {
a.do_stuff();
}
你的程序会被操作系统杀死因为a
在错误的内存(实际上是 0x0 内存)上引用了对象。
关于 nullptr 取消引用的一个相关问题是 Here .
关于c++ - move 后使用 unique_ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45400704/