c++ - unique_ptr<T>.get() 方法在使用原始指针分配时调用析构函数?

标签 c++ pointers c++11 crash unique-ptr

下面的程序使用std::unique_ptr<T>避免手动内存管理。我尝试过两种方法来实现它。问题出在第二种方法中,在分配给原始指针之前,析构函数被调用。这会导致程序崩溃,因为后面的代码会尝试访问无效内存。

我在第二种方法中的意图是,如何将智能指针与现有代码库一起使用,以便我可以利用智能指针提供的自动内存管理。因此,我没有更改声明中的指针类型(即从 Widget* wstd::unique_ptr<Widget> w )。

有人可以详细解释一下吗?最佳做法应该是什么?。或者我遗漏了什么?

#include<iostream>
#include<memory>
class Widget {
public:
    Widget() { std::cout << "Widget::Widget()" << std::endl; }
    virtual ~Widget() { std::cout << "Widget::~Widget()" << std::endl; }
    virtual void draw() = 0;
};

class WindowsButton : public Widget {
public:
    WindowsButton() = default;
    ~WindowsButton() = default;
    void draw() { std::cout << "WindowsButton"<<std::endl; }
};

int main() {    
    // Working Code
    // std::unique_ptr<Widget> w = std::unique_ptr<Widget>(new WindowsButton());
    // w.get()->draw();

    //In this way program is crashing while calling the w->draw()
    Widget* w = std::unique_ptr<Widget>(new WindowsButton()).get();
    w->draw();
}

最佳答案

在第二种情况下,您正在创建一个 unique_ptr 的临时实例,并在其上调用 get() 成员函数。 unique_ptr 对象将在完整表达式的末尾(分号处)被销毁。

Widget* w = std::unique_ptr<Widget>(new WindowsButton()).get();
//          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^      ^
//          unnamed temporary instance                        destroyed here

当然,当实例被销毁时,unique_ptr删除 托管对象,并调用 ~Widget()

w->draw();

然后将取消引用指向无效内存位置的指针,从而导致未定义的行为。

关于c++ - unique_ptr<T>.get() 方法在使用原始指针分配时调用析构函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25541118/

相关文章:

c++ - 找到数字属于哪个部分的快速方法是什么(在 C++ 中使用 vector )?

c - 收到警告 - 在 C 代码中可能为 null 之前取消引用

c++ - 如何在 C++11 中将容器 std::array<type, size> 用于多维数组?

c - C 中带有指针的结构的内存开销

c++ - 显式实例化类模板中的自动构造函数

c++ - it.first 和 it->first 有什么区别?

c++ - 是否可以向 QStandardItem 添加自定义类?

Android NDK 包含 Eigen

C++ - 捕获所有异常?

c++ - Windows:在 C++ 中获取函数地址