我正在阅读一些关于智能指针如何在 C++ 中工作的教程,但我坚持我尝试的第一个:唯一指针。我正在遵循wikipediacppreferencecplusplus的准则。我也已经看过 this answer 了。如果我理解正确的话,唯一指针应该是对某个内存单元/块拥有所有权的唯一指针。这意味着只有唯一指针(应该)指向该单元格,而没有其他指针。从维基百科,他们使用以下代码作为示例:

std::unique_ptr<int> p1(new int(5));
std::unique_ptr<int> p2 = p1; //Compile error.
std::unique_ptr<int> p3 = std::move(p1); //Transfers ownership. p3 now owns the memory and p1 is rendered invalid.

p3.reset(); //Deletes the memory.
p1.reset(); //Does nothing.

直到第二行,当我测试它时,这对我来说很好用。但是,在将第一个唯一指针移动到第二个唯一指针后,我发现两个指针都可以访问同一个对象。我认为整个想法是让第一个指针变得无用可以这么说?我期望一个空指针或一些未确定的结果。我运行的代码:
class Figure {
public:
    Figure() {}

    void three() {
        cout << "three" << endl;
    }

};

class SubFig : public Figure {
public:
    void printA() {
        cout << "printed a" << endl;
    }
};

int main()
{
    unique_ptr<SubFig> testing (new SubFig());
    testing->three();
    unique_ptr<SubFig> testing2 = move(testing);
    cout << "ok" << endl;
    int t;
    cin >> t; // used to halt execution so I can verify everything works up til here
    testing->three(); // why is this not throwing a runtime error?
}

在这里,testing 已移至 testing2 ,所以我惊讶地发现我仍然可以在 three() 上调用 testing 方法。

此外,调用 reset() 似乎并没有像它所说的那样删除内存。当我修改 main 方法成为:
int main()
{
    unique_ptr<SubFig> testing (new SubFig());
    testing->three();
    unique_ptr<SubFig> testing2 = move(testing);
    cout << "ok" << endl;
    int t;
    cin >> t;
    testing.reset(); // normally this should have no effect since the pointer should be invalid, but I added it anyway
    testing2.reset();
    testing2->three();
}

在这里,我希望three()不适用于testing2,因为来自维基百科的示例提到应通过重置来删除内存。我仍然打印出打印的,好像一切都很好。这对我来说似乎很奇怪。

那么任何人都可以向我解释为什么:
  • 从一个唯一指针移动到另一个唯一指针不会使第一个指针无效?
  • 重置实际上并没有删除内存?调用 reset() 时实际发生了什么?
  • 最佳答案

    本质上,您通过空指针调用成员函数:

    int main()
    {
        SubFig* testing = nullptr;
        testing->three();
    }
    

    ...这是未定义的行为。

    从 20.8.1 类模板 unique_ptr (N4296)



    (强调我的)

    关于c++ - 移动后唯一指针仍保持对象,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38027402/

    10-11 22:54
    查看更多