首页  

C++11 智能指针     所属分类 c 浏览量 839
unique_ptr shared_ptr weak_ptr 
C++98 的 auto_ptr 在 c++11中 已经废弃

智能指针主要用于管理在堆上分配的内存,将普通的指针封装为一个栈对象
当栈对象的生存周期结束后,会在析构函数中释放掉申请的内存,从而防止内存泄漏
在函数结束时自动释放内存空间

C++11中最常用的智能指针类型为shared_ptr,
采用引用计数的方法,记录当前内存资源被多少个智能指针引用
新增一个时引用计数加1,当过期时引用计数减一
引用计数为0时,智能指针自动释放引用的内存资源

不能将一个普通指针直接赋值给智能指针,因为一个是指针,一个是类


auto_ptr<string> p1 (new string ("hello")); 
auto_ptr<string> p2; 
p2 = p1; //auto_ptr不会报错.
p2剥夺了p1的所有权,但访问p1将会报错
auto_ptr 存在潜在的内存崩溃问题

unique_ptr
实现独占式拥有或严格拥有概念,保证同一时间内只有一个智能指针指向该对象
unique_ptr<string> p3 (new string ("auto")); 
unique_ptr<string> p4;
p4 = p3;// 编译报错
编译器认为p4=p3非法,避免p3不再指向有效数据的问题
unique_ptr比auto_ptr更安全

std::move() 将一个unique_ptr赋给另一个
转移所有权后  对原有指针访问会奔溃

boost库的boost::scoped_ptr也是一个独占性智能指针
但是它不允许转移所有权,更安全谨慎


shared_ptr
共享式拥有概念
多个智能指针指向同一个对象
使用计数机制来表明资源被几个指针共享

use_count 返回引用计数的个数
unique    返回是否是独占所有权( use_count 为 1)
swap      交换两个 shared_ptr 对象(即交换所拥有的对象)
reset     放弃内部对象的所有权或拥有对象的变更, 原有对象引用计数减少
get       返回内部对象(指针), 由于已经重载了()方法, 因此和直接使用对象是一样的

shared_ptr<int> sp(new int(1)); 
sp 与 sp.get()是等价的

int main()
{
	string *s1 = new string("s1");

	shared_ptr<string> ps1(s1);
	shared_ptr<string> ps2;
	ps2 = ps1;

	cout << ps1.use_count()<<endl;	//2
	cout<<ps2.use_count()<<endl;	//2
	cout << ps1.unique()<<endl;	//0

	string *s3 = new string("s3");
	shared_ptr<string> ps3(s3);

	cout << (ps1.get()) << endl;	 
	cout << ps3.get() << endl;	 
	swap(ps1, ps3);	//交换所拥有的对象
	cout << (ps1.get())<<endl;	 
	cout << ps3.get() << endl;	 

	cout << ps1.use_count()<<endl;	//1
	cout << ps2.use_count() << endl;	//2
	ps2 = ps1;
	cout << ps1.use_count()<<endl;	//2
	cout << ps2.use_count() << endl;	//2
	ps1.reset();	//放弃ps1的拥有权,引用计数减少
	cout << ps1.use_count()<<endl;	//0
	cout << ps2.use_count()<<endl;	//1
}


shared_ptr 循环引用,使引用计数失效,导致内存泄漏


weak_ptr
解决shared_ptr相互引用死锁问题


lock      获得一个可用的 shared_ptr 对象
expired   管理的对象是否已经释放
use_count 
reset

weak_ptr 支持拷贝或赋值, 但不会影响对应的 shared_ptr 内部对象的计数




#include "iostream"
#include "memory"
#include "string"
using namespace std;
int main(){  
   
    std::auto_ptr<std::string> p1 (new std::string ("hello,auto_ptr")); 
    std::auto_ptr<std::string> p2; 
    p2 = p1; //auto_ptr不会报错.
    
    // Segmentation fault: 11
    // std::cout << *p1 << std::endl;
    
    std::cout << *p2 << std::endl;
    
    // 
    unique_ptr<string> p3 (new string ("hello,unique_ptr")); 
    unique_ptr<string> p4;
    // 编译报错
    // p4 = p3;
    std::cout << *p3 << std::endl;
}



完整代码
https://gitee.com/dyyx/hellocode/blob/master/web/tech/cpp/demo/smartptr001.cpp

上一篇     下一篇
c/c++标准预定义宏

c++ 结构体例子

c++ 面向对象 例子

C++类成员初始化

c++ 初始化列表

C++ 花括号和括号初始化的区别