实战c++中的智能指针unique_ptr系列-- unique_ptr的get()赋给普通指针后的崩溃(其实是生命周期惹的祸)

Posted 一苇渡江694

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实战c++中的智能指针unique_ptr系列-- unique_ptr的get()赋给普通指针后的崩溃(其实是生命周期惹的祸)相关的知识,希望对你有一定的参考价值。

今天遇到一个错误,是关于unique_ptr的get方法的,忽略了。

之前博客是这样写get方法的:
其中bar是一个智能指针,p是一个普通指针:

p = bar.get(); 后,bar并非被释放,也就相当于指针p和智能指针bar共同管理一个对象,所以就*p做的一切,都会反应到bar指向的对象上。

那么来看今天的代码:

#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() 
     std::unique_ptr<Widget> w = std::unique_ptr<Widget>(new WindowsButton());
     w.get()->draw();
     w->draw();

输出:
Widget::Widget()
WindowsButton
WindowsButton
Widget::~Widget()

就是使用w.get()和直接使用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() 

    Widget* w = std::unique_ptr<Widget>(new WindowsButton()).get();
    w->draw();

上面的代码再执行w->draw()的时候会崩溃,why?

首先呢,这么写代码纯是吃饱撑的。
智能指针就是帮助我们管理内存的,为何又要赋值给普通指针呢?
好,即使你写了这样的代码,也是对变量生命周期不是很了解:

Widget* w = std::unique_ptr<Widget>(new WindowsButton()).get();

由于 unique_ptr 拥有对象,所以当unique_ptr 被摧毁的时候,它所指向的对象也会销毁,所以接下来的w指针指向的是一个已经销毁的对象,于是调用这个已经销毁对象的成员函数当然是错误的,导致崩溃。

个人觉得,尽量避免使用get方法,既然unique_ptr给我们提供了那么多的便利条件,我们就不应该铤而走险。

个人还觉得,尽量避免智能指针和普通指针的混合,那样容易非常的乱,导致内存泄露,导致崩溃。

以上是关于实战c++中的智能指针unique_ptr系列-- unique_ptr的get()赋给普通指针后的崩溃(其实是生命周期惹的祸)的主要内容,如果未能解决你的问题,请参考以下文章

C++从青铜到王者第二十五篇:C++智能指针

C++中的智能指针

C++进阶---智能指针

C++进阶---智能指针

[C++]智能指针unique_ptr,shared_ptr,weak_ptr

智能指针之 unique_ptr