- 智能指针的作用就是为了防止内存泄漏
- 使用普通指针的现象:如果malloc和free之间存在抛异常,即malloc执行后没有执行free就推出了等一系列没有释放资源的问题
- 应满足:1.能自动释放内存->降低了内存泄漏。2. 还能当指针来用
- 智能指针中使用RAII->编译器自动调用函数释放内存—-使我们想到类中编译器自动调用的构造和析构函数。把指针封装成一个类,在构造中创造资源,在析构中释放资源
- 用_CrtDumpMemoryLeaks()函数可以检测内存泄漏
- 智能指针的实现原理:
- 1.RAII达到资源自动释放(就是用一个类来管理堆上的资源,利用的是编译器自动调用的原理),和string里管理的指针的区别是,智能指针管理是管理类外申请的堆上的空间.
- 2.具有指针类似的操作*和->,(这两个简单)重载这两个操作符就行
- 3.解决浅拷贝的方式,不能用深拷贝解决,和string的区别是string的资源是在类内部申请的,智能指针是管理类外的指针,这是区别,所以不能像string一样深拷贝。智能指针的头文件#include<memory>
- c++98提供auto_ptr。 。 使用方法,auto_ptr<int>ptr(new int);auto_ptr不使用。拷贝构造的方法是,转移资源的的管理,将p1管理的资源转移给p2,p2管理资源,p1内部的资源null。不用的原因就是这样导致p1不能使用,但是程序员不知道,访问p1就存在问题
- c++98~11之间的改进:不用浅拷贝的原因是为了避免释放多次,不用auto_ptr是因为有一个指针不能使用。改进后两个指针都能指向这个空间,都有使用权利,但是只有一个指针能释放这片空间。在成员变量里标记一个这对象能不能delete,就是这个对象有没有管理权力。这个方法也不推荐用。缺陷可能会造成野指针。函数中的小{}作用域里把对象有释放权利的对象析构里,那后面指向这片空间的指针就成夜指针里。访问就会出错。
- c++11又使用资源转移的方法,补98的坑。使用unique_ptr简单粗暴式解决浅拷贝,资源独占。不让拷贝和 赋值,不让拷贝的实现原理,c++11:unique_ptr(const unique_ptr<T>&)=delete;拷贝构造这么实现就是告诉编译器,拷贝构造不用编译器生成了。c++11中扩充了delete的功能,控制编译器生成默认的成员函数。c++98:通过把拷贝构造的声明设置为私有的的成员函数,但是不定义函数体,给成私有原因是,私有的即使在类外把函数体定义了,也调不了。只给声明是因为给出来没有意义,因为本来的目的就是不想要这个函数...就写这个
- 对于连续的空间一般不使用unique_ptr(智能指针)管理,直接使用vector就行了
- unique_ptr的缺陷是多个对象之间不能共享资源就是不能进行拷贝和赋值
- shared_ptr:共享智能指针,解决浅拷贝的方式:引用计数,解决unique_ptr不能拷贝的问题和.只有引用计数为1的时候析构的时候才delete.还有:引用计数不能设置为staic静态成员变量,因为静态成员变量是所有对象又能访问到的,,现在需要的是同一份资源用一个计数.所以同一份资源要多包括一份维护一个引用计数的指针--->这个要考虑线程安全的问题.线程安全解决之后还有在加锁和解锁之间可能存在异常,抛异常就直接退出,所以就造成死锁,所以再用类包装锁(包装锁时要注意成员变量要时引用类型,否则就不是一把锁了),退出就是函数结束或者是出了作用域,自动调用析构解锁了....还有share_ptr存在循环引用,导致的后果就是资源泄露
- shared_ptr解决循环引用的方式:weak_ptr,唯一的作用就是协助shared_ptr解决循环引用的问题,他不能独立管理资源.::::原理是,底层基类维护两套应用计数.use为0就是释放资源了,weak为0就能释放引用计数的资源了
- 只能是智能指针之间相互赋值和指向,普通指针和智能指针之间不能指向,例如赋值来说,是用一个对象给另一个对象拷贝,普通指针就干不了这事,shared_pte也能管理不是new出来的指针,但是weak_ptr只能管理别人的资源