关于c++智能指针及循环引用的问题
c++智能指针介绍
创新互联建站致力于成都做网站、网站制作,成都网站设计,集团网站建设等服务标准化,推过标准化降低中小企业的建站的成本,并持续提升建站的定制化服务水平进行质量交付,让企业网站从市场竞争中脱颖而出。 选择创新互联建站,就选择了安全、稳定、美观的网站建设服务!
由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete,比如流程太复杂,最终导致没有 delete,异常导致程序过早退出,没有执行 delete 的情况并不罕见,并造成内存泄露。如此c++引入 智能指针 ,智能指针即是C++ RAII的一种应用,可用于动态资源管理,资源即对象的管理策略。 智能指针在
c++智能指针类别
c++ 智能指针主要包括:unique_ptr,shared_ptr, weak_ptr, 这三种,其中auto_ptr 已被遗弃。
unique_ptr
只允许基础指针的一个所有者。 可以移到新所有者(具有移动语义),但不会复制或共享(即我们无法得到指向同一个对象的两个unique_ptr)。 替换已弃用的 auto_ptr。 相较于 boost::scoped_ptr。 unique_ptr 小巧高效;大小等同于一个指针,支持 rvalue 引用,从而可实现快速插入和对 STL 集合的检索。 头文件:
使用unique_ptr,可以实现以下功能:
1、为动态申请的内存提供异常安全。
2、将动态申请内存的所有权传递给某个函数。
3、从某个函数返回动态申请内存的所有权。
4、在容器中保存指针。
5、所有auto_ptr应该具有的(但无法在C++ 03中实现的)功能。
如下代码所示:
class A; // 如果程序执行过程中抛出了异常,unique_ptr就会释放它所指向的对象 // 传统的new 则不行 unique_ptr fun1() { unique_ptr p(new A); //do something return p; } void fun2() { // unique_ptr具有移动语义 unique_ptr p = f();// 使用移动构造函数 // do something }// 在函数退出的时候,p以及它所指向的对象都被删除释放 shared_ptr
基本操作:shared_ptr的创建、拷贝、绑定对象的变更(reset)、shared_ptr的销毁(手动赋值为nullptr或离开作用域)、指定deleter等操作。
一,使用函数make_shared(会根据传递的参数调用动态对象的构造函数);
二,使用构造函数(可从原生指针、unique_ptr、另一个shared_ptr创建)
shared_ptr
循环引用问题可以参考 这个链接 上的问题理解,“循环引用”简单来说就是:两个对象互相使用一个shared_ptr成员变量指向对方的会造成循环引用。导致引用计数失效。下面给段代码来说明循环引用:
#include#include pa; shared_ptr pa; ~B() { cout <<"kill B\n"; } }; int main(int argc, char** argv) { shared_ptr sa(new A()); shared_ptr sb(new B()); if(sa && sb) { sa->pb=sb; sb->pa=sa; } cout<<"sa use count:"<using namespace std; class B; class A { public:// 为了省去一些步骤这里 数据成员也声明为public //weak_ptr pb; shared_ptr pb; void doSomthing() { // if(pb.lock()) // { // // } } ~A() { cout << "kill A\n"; } }; class B { public: //weak_ptr
上面的代码运行结果为:sa use count:2, 注意此时sa,sb都没有释放,产生了内存泄露问题!!!
即A内部有指向B,B内部有指向A,这样对于A,B必定是在A析构后B才析构,对于B,A必定是在B析构后才析构A,这就是循环引用问题,违反常规,导致内存泄露。
一般来讲,解除这种循环引用有下面有三种可行的方法( 参考 ):
1 . 当只剩下最后一个引用的时候需要手动打破循环引用释放对象。
2 . 当A的生存期超过B的生存期的时候,B改为使用一个普通指针指向A。
虽然这三种方法都可行,但方法1和方法2都需要程序员手动控制,麻烦且容易出错。我们一般使用第三种方法:弱引用的智能指针weak_ptr。
#include#include pa; shared_ptr pa; ~B() { cout <<"kill B\n"; } }; int main(int argc, char** argv) { shared_ptr sa(new A()); shared_ptr sb(new B()); if(sa && sb) { sa->pb=sb; sb->pa=sa; } cout<<"sb use count:"<using namespace std; class B; class A { public:// 为了省去一些步骤这里 数据成员也声明为public weak_ptr pb; //shared_ptr pb; void doSomthing() { if(pb.lock()) { } } ~A() { cout << "kill A\n"; } }; class B { public: //weak_ptr
以上就是小编为大家带来的关于c++ 智能指针及 循环引用的问题全部内容了,希望大家多多支持创新互联~
当前标题:关于c++智能指针及循环引用的问题
本文路径:http://tjjierui.cn/article/iejihh.html