实战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()赋给普通指针后的崩溃(其实是生命周期惹的祸)的主要内容,如果未能解决你的问题,请参考以下文章