移动后使用unique_ptr

时间:2017-07-30 14:10:45

标签: c++ move-semantics unique-ptr

我不明白为什么这段代码有效:

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;是编译错误。

我将理解有关正在发生的事情的澄清。

2 个答案:

答案 0 :(得分:1)

首先,声明

auto &a = *pt;

未定义行为,未定义。在C ++中取消引用nullptr不会使崩溃您的程序,它可能会发生一切。

您可能希望从代码中获得segmentation fault,但不会发生这种情况,因为您实际上无法访问对象a

的确,您的operator<<会占用Base个对象,但根本不会使用它。

相反,如果您尝试执行以下操作:

friend ostream& operator<<(ostream& out, const Base& a) {
     a.do_stuff();
}

您的程序将被操作系统杀死,因为错误的内存(实际上是0x0内存)引用了a对象。

有关nullptr derefereing的相关问题是Here

答案 1 :(得分:0)

auto npt = move(pt);pt的所有权转移到nptpt一个nullptr。由于pt现在是nullptr,因此if (pt == nullptr) cout << "yes nullptr" << endl;正确输出“yes nullptr”。

auto &a = *pt;表示您尝试取消引用nullptr这只是未定义的行为cout << a << endl;可能会导致任何可能发生的事情,但不一定会导致程序崩溃。