c/c++ 智能指针 shared_ptr 使用

时间:2022-12-24 18:10:24

智能指针 shared_ptr 使用

上一篇智能指针是啥玩意,介绍了什么是智能指针。

这一篇简单说说如何使用智能指针。

一,智能指针分3类:今天只唠唠shared_ptr

  • shared_ptr
  • unique_ptr
  • weak_ptr

二,下表是shared_ptr和unique_ptr都支持的操作

操作 功能描述
shared_ptr<T> sp 空智能指针,可以指向类型为T的对象
unique_ptr<T> up 空智能指针,可以指向类型为T的对象
p 将p用作一个条件判断,如果p指向一个对象,则为true
*p 解引用p,获得它指向的对象
p->mem 等价于(*p).mem,访问p所指对象的mem成员
p.get() 返回p中保存的指针。如果指向的对象已经被释放,就是一个危险的指针
swap(p, q)或者p.swap(q) 交换p和q中的指针

上面操作的验证代码

#include <memory>
#include <iostream>
#include <vector> using namespace std; class Test{
public:
Test(int d = 0):data(d){cout << "cr:" << data << endl;}
~Test(){cout << "fr:" << data << endl;}
void fun(){
cout << "Test func(" << data << ")" << endl;
}
private:
int data;
};
int main(){
//shared_ptr<Test> sp = make_shared<Test>();
Test* pt = new Test();
shared_ptr<Test> sp(pt);
if(sp){
cout << "sp指向了对象" << endl;
}
(*sp).fun();
shared_ptr<int> isp;
if(!isp){
cout << "isp没有指向对象" << endl;
}
Test* tmp1 = sp.get();
auto sp1 = make_shared<Test>(10);
Test* tmp2 = sp1.get();
swap(sp, sp1);
tmp1->fun();//0
tmp2->fun();//10
//sp和sp1所指向的对象被交换了
sp.get()->fun();//10
sp1.get()->fun();//0 }

三,下表是shared_ptr独有的操作

操作 功能描述
make_shared<T>(args) 返回shared_ptr,指向一个动态分配的类型为T的对象。使用args初始化此对象。
shared_ptr p(q) p是q的拷贝;递增q中的计数器。q中的指针必须能转化成T*。
p = q p和q都是shared_ptr,所保存的指针必须能相互转换。递减p的引用计数;递增q的引用计数;如果p的引用计数变为0,则释放p管理的对象的内存。
p.unique() 如果p.use_count()为1,则返回true;否则返回false
p.use_count() 返回与p共享对象的智能指针的数量;性能很低,用于调试。

上面操作的验证代码

  shared_ptr<Test> tsp = make_shared<Test>(11);
cout << tsp.use_count() << endl;//1
//tsp1和tsp指向相同的对象,这个对象的计数器加1
shared_ptr<Test> tsp1(tsp);
cout << tsp.use_count() << endl;//2
//用tsp1改变了对象的data的值,所以用tsp再访问这个对象,发现对象被改变了
tsp1->setData(111);
tsp->fun();//111 shared_ptr<Test> q(new Test(20));
cout << q.use_count() << endl;//1
cout << tsp.use_count() << endl;//2
//如果q不是智能指针,q指向的Test(20)这块内存就泄露了
//q是智能指针,所以自动释放了Test(20)这块内存
q = tsp;
cout << q.use_count() << endl;//3
cout << tsp.use_count() << endl;//3
if(!q.unique()){
cout << "不是只有一个智能指针指向了某个对象" << endl;
}

四,智能指针作为函数的返回值

shared_ptr<Test> hun(int d){
return make_shared<Test>(d);
}
void use_hun1(int d){
shared_ptr<Test> p = hun(d);
p->fun();
}//p离开作用域后,它指向的内存会被自动释放
shared_ptr<Test> use_hun2(int d){
shared_ptr<Test> p = hun(d);//计数器为1
return p;//返回p时,计数器递增,为2
}//离开作用域后,计数器递减,为1,因为不为0,所以不会释放

一到四的小例子:

include <memory>
#include <iostream>
#include <vector> using namespace std; class Test{
public:
Test(int d = 0):data(d){cout << "cr:" << data << endl;}
~Test(){cout << "fr:" << data << endl;}
void fun(){
cout << "Test func(" << data << ")" << endl;
}
void setData(int d){
data = d;
}
private:
int data;
}; //test3 智能指针作为函数的返回值
shared_ptr<Test> hun(int d){
return make_shared<Test>(d);
}
void use_hun1(int d){
shared_ptr<Test> p = hun(d);
p->fun();
}//p离开作用域后,它指向的内存会被自动释放
shared_ptr<Test> use_hun2(int d){
shared_ptr<Test> p = hun(d);//计数器为1
return p;//返回p时,计数器递增,为2
}//离开作用域后,计数器递减,为1,因为不为0,所以不会释放
int main(){
//test1 shared_ptr和unique_ptr都支持的操作
/*
//shared_ptr<Test> sp = make_shared<Test>();
Test* pt = new Test();
shared_ptr<Test> sp(pt);
if(sp){
cout << "sp指向了对象" << endl;
}
(*sp).fun();
shared_ptr<int> isp;
if(!isp){
cout << "isp没有指向对象" << endl;
}
Test* tmp1 = sp.get();
auto sp1 = make_shared<Test>(10);
Test* tmp2 = sp1.get();
swap(sp, sp1);
tmp1->fun();
tmp2->fun();
sp.get()->fun();
sp1.get()->fun();
*/ //test2 shared_ptr独有的操作
/*
shared_ptr<Test> tsp = make_shared<Test>(11);
cout << tsp.use_count() << endl;//1
//tsp1和tsp指向相同的对象,这个对象的计数器加1
shared_ptr<Test> tsp1(tsp);
cout << tsp.use_count() << endl;//2
//用tsp1改变了对象的data的值,所以用tsp再访问这个对象,发现对象被改变了
tsp1->setData(111);
tsp->fun();//111 shared_ptr<Test> q(new Test(20));
cout << q.use_count() << endl;//1
cout << tsp.use_count() << endl;//2
//如果q不是智能指针,q指向的Test(20)这块内存就泄露了
//q是智能指针,所以自动释放了Test(20)这块内存
q = tsp;
cout << q.use_count() << endl;//3
cout << tsp.use_count() << endl;//3
if(!q.unique()){
cout << "不是只有一个智能指针指向了某个对象" << endl;
}
*/ //test3 智能指针作为函数的返回值
/*
auto ap = use_hun2(22);
ap->fun();
use_hun1(33);
*/ }

github完整代码

五,智能指针的注意事项

把shared_ptr放入容器中时,之后不再需要全部元素,只使用其中一部分的话,要用erase删除那些不再需要使用的shared_ptr。如果不erase那些不再需要使用的shared_ptr,shared_ptr就不会释放它指向的内存。

六,智能指针的小例子,让多个对象共享相同的状态。

  • 有个类shared_vector,里面有个shared_ptr,指向了一个vector,类shared_vector的对象a2拷贝a1时,实现a1和a2共享vector。
  • 类un_shared_vector没有使用shared_ptr,所以没有共享vector。
include <iostream>
#include <memory>
#include <vector>
#include <string> using namespace std; class shared_vector{
public:
typedef vector<string>::size_type size_type;
shared_vector():data(make_shared<vector<string>>()){}
shared_vector(initializer_list<string> il):
data(make_shared<vector<string>>(il)){}
size_type size()const{return data->size();}
bool empty()const{return data->empty();}
//尾部插入,删除元素
void push_back(const string& s){data->push_back(s);}
void pop_back(){data->pop_back();}
//访问元素
string& front(){return data->front();}
string& back(){return data->back();} private:
shared_ptr<vector<string>> data;
}; class un_shared_vector{
public:
typedef vector<string>::size_type size_type;
un_shared_vector():data(vector<string>()){}
un_shared_vector(initializer_list<string> il):data(il){}
size_type size()const{return data.size();}
bool empty()const{return data.empty();}
//尾部插入,删除元素
void push_back(const string& s){data.push_back(s);}
void pop_back(){data.pop_back();}
//访问元素
string& front(){return data.front();}
string& back(){return data.back();} private:
vector<string> data;
}; int main(){
shared_vector sv{"aa","bb"};
shared_vector sv1(sv);
//因为sv和sv1共享同一个vector,
//所以通过sv改变vector后,通过sv1也发现了相同的改变
sv.push_back("cc");
cout << sv1.back() << endl; un_shared_vector usv{"11","22"};
un_shared_vector usv1(usv);
//因为usv和usv1不共享同一个vector,
//所以通过usv改变vector后,usv1里面的vector没有跟着变化
usv.push_back("33");
cout << usv1.back() << endl;
cout << usv.back() << endl;
}

github完整代码

c/c++ 学习互助QQ群:877684253

c/c++ 智能指针 shared_ptr 使用

本人微信:xiaoshitou5854

c/c++ 智能指针 shared_ptr 使用的更多相关文章

  1. c&sol;c&plus;&plus; 智能指针 shared&lowbar;ptr 和 new结合使用

    智能指针 shared_ptr 和 new结合使用 用make_shared函数初始化shared_ptr是最推荐的,但有的时候还是需要用new关键字来初始化shared_ptr. 一,先来个表格,唠 ...

  2. C&plus;&plus;智能指针shared&lowbar;ptr

    shared_ptr 这里有一个你在标准库中找不到的—引用数智能指针.大部分人都应当有过使用智能指针的经历,并且已经有很多关于引用数的文章.最重要的一个细节是引用数是如何被执行的—插入,意思是说你将引 ...

  3. STL源码剖析-智能指针shared&lowbar;ptr源码

    目录一. 引言二. 代码实现 2.1 模拟实现shared_ptr2.2 测试用例三. 潜在问题分析 你可能还需要了解模拟实现C++标准库中的auto_ptr一. 引言与auto_ptr大同小异,sh ...

  4. 智能指针shared&lowbar;ptr的用法

    为了解决C++内存泄漏的问题,C++11引入了智能指针(Smart Pointer). 智能指针的原理是,接受一个申请好的内存地址,构造一个保存在栈上的智能指针对象,当程序退出栈的作用域范围后,由于栈 ...

  5. 智能指针 shared&lowbar;ptr 解析

    近期正在进行<Effective C++>的第二遍阅读,书里面多个条款涉及到了shared_ptr智能指针,介绍的太分散,学习起来麻烦.写篇blog整理一下. LinJM   @HQU s ...

  6. 智能指针shared&lowbar;ptr

    // 智能指针会自动释放所指向的对象. // shared_ptr的应用场景是:程序需要在多个对象间共享数据 /* 先从应用场景入手吧,说矿工A发现了一个金矿. * 然后矿工A喊来了矿工B,一起开采, ...

  7. 智能指针shared&lowbar;ptr新特性shared&lowbar;from&lowbar;this及weak&lowbar;ptr

    enable_shared_from_this是一个模板类,定义于头文件<memory>,其原型为: template< class T > class enable_shar ...

  8. C&plus;&plus; 智能指针 shared&lowbar;ptr

    今天晚上去旁听了C++高级编程的课,其中提到智能指针.第一反映还以为是auto_ptr呢,一听才知道是share_ptr这个.哦,原来是C++11特性.大致的原因是auto_ptr有一点缺陷,而sha ...

  9. 标准库中的智能指针shared&lowbar;ptr

    智能指针的出现是为了能够更加方便的解决动态内存的管理问题.注:曾经记得有本书上说可以通过vector来实现动态分配的内存的自动管理,但是经过试验,在gcc4.8.5下是不行的.这个是容易理解的,vec ...

随机推荐

  1. Win32 OpenProcess打开进程失败,返回5无权限操作

    Win32 OpenProcess打开进程失败,返回5无权限操作,相信你会碰到这样的事,在IDE中可以,单独却不可以了,其实这时就需要提权了,否则是无法打开的,OpenProcess提权至Debug即 ...

  2. C&num;动态编译引擎-CS-Script

    什么是CS-Script? CS-Script是一种以CLR(公共语言运行库)为基础的脚本系统,它使用ECMA标准的C#作为编程语言,它面向微软的CLR运行库(.net 2.0/3.0/3.5/4.0 ...

  3. java 记事本 - 实例

    记事本记事本实例中使用了以下知识1.ui界面2.io流3.事件监听4.图形5.JFileChooser 类,用于打开文件,另存为文件.弹出文件选择器对话框 学习重点:JFileChooser,有很多方 ...

  4. Bootstrap页面布局5 - 响应式布局&lpar;格式&rpar;

    旨在优化不同上网设备中页面显示的优化 响应式布局:就是根据浏览窗口的尺寸,改变页面的变化 原理:利用css的media-queries判断浏览窗口的尺寸,在CSS样式表中设置一些规则! 例如: 在&l ...

  5. iOS - UI - UISlider

    6.UISlider //滑块   设置高度 UISlider * slider = [[UISlider alloc] initWithFrame:CGRectMake(20, 100, CGRec ...

  6. Android自动化测试之Monkeyrunner从零开始&lpar;三&rpar;

    转自http://www.51testing.com/html/81/22381-854342.html 时光过得太快了,一晃离上一篇monkeyrunner系列的博客已经一年多了.这一年多时间经历了 ...

  7. paxos 实现

    原文地址:http://rdc.taobao.com/blog/cs/?p=162 本文主要介绍zookeeper中zookeeper Server leader的选举,zookeeper在选举lea ...

  8. 英文Ubantu系统安装中文输入法

    以前都是安装的中文Ubantu,但是有时候用命令行的时候中文识别不好,会出现错误,所以这次安装了英文版,但是安装后发现输入法不好用,于是就要自己安装输入法. 安装环境为Ubantu13.04 1.卸载 ...

  9. 【转】Angular Input格式化

    今天在Angular中文群有位同学问到:如何实现对input box的格式化.如下的方式对吗? <input type="text" ng-model="demo. ...

  10. Laravel 5&period;2 教程 - 文件上传

    一.简介 Laravel 有很棒的文件系统抽象层,是基于 Frank de Jonge 的 Flysystem 扩展包. Laravel 集成的 Flysystem 提供了简单的接口,可以操作本地端空 ...