手写代码是理解C++的最好办法,以几个例子说明C++四个智能指针的用法,转载请注明出处。

一、auto_ptr

  auto_ptr这是C++98标准下的智能指针,现在常常已经被C++标准的其他智能指针取代。它的缺点是在转移所有权后会使运行期不安全。C++11新标准,用unique_ptr来代替auto_ptr原有功能,其用法介绍见第四部分unique_ptr。

#include <iostream>
#include <memory>
#include <string>
using namespace std; void main(){
auto_ptr<string> country[] =
{
auto_ptr<string>(new string("USA")),
auto_ptr<string>(new string("CHN")),
auto_ptr<string>(new string("RUS")),
auto_ptr<string>(new string("FRA")),
auto_ptr<string>(new string("GRB"))
}; auto_ptr<string> pwin;
pwin = country[]; //将所有权从country[2]转让给pwin,此时country[2]不再引用该字符串从而变成空指针,在运行到循环时就会崩溃 for (int i = ; i < ; ++i)
cout << *country[i] << endl;//运行到[2]时崩溃,因为country[2]为空
cout << "The best is " << *pwin << endl; system("pause");
}

二、share_ptr

  share_ptr是C++11新添加的智能指针,它限定的资源可以被多个指针共享。

用法见下例:

#include <iostream>
#include <memory>
#include <string>
using namespace std; void fun(){
shared_ptr<string> pa(new string("CHN"));
shared_ptr<string> pb(new string("USA"));
cout << "*pa " << *pa << endl;//CHN
cout << "pa.use_count " << pa.use_count() << endl;//
cout << "*pb " << *pb << endl;//USA
cout << "pb.use_count " << pb.use_count() << endl;// pa = pb;
cout << *pa << endl;//USA
cout << "pa.use_count " << pa.use_count() << endl;//2:pa和pb指向同一个资源USA了,该资源的计数为2,所以pb、pb都输出2
cout << "pb.use_count " << pb.use_count() << endl;// pa.reset();
pb.reset();
cout << "pa.use_count " << pa.use_count() << endl;//
cout << "pb.use_count " << pb.use_count() << endl;//
} void main()
{
fun();
system("pause");
}

  与数组相结合应用,见另一个例子:

#include <iostream>
#include <memory>
#include <string>
using namespace std; void main(){
shared_ptr<string> country[] =
{
shared_ptr<string>(new string("USA")),
shared_ptr<string>(new string("CHN")),
shared_ptr<string>(new string("RUS")),
shared_ptr<string>(new string("FRA")),
shared_ptr<string>(new string("GRB"))
}; shared_ptr<string> pwin;
cout << pwin.use_count() << endl;//输出0
pwin = country[];
/*使用shared_ptr时运行正常,因为shared_ptr采用引用计数,pwin和films[2]都指向同一块内存,
在释放空间时因为事先要判断引用计数值的大小因此不会出现多次删除一个对象的错误。 从名字share就可以看出了资源可以被多个指针共享,它使用计数机制来表明资源被几个指针共享。
可以通过成员函数use_count()来查看资源的所有者个数。
*/
cout << pwin.use_count() << endl;//输出2 for (int i = ; i < ; ++i)
cout << *country[i] << endl;//运行到[2]时崩溃,因为country[2]为空
cout << "The best is " << *pwin << endl; system("pause");
}

三、weak_ptr

  weak_ptr是一种用于解决shared_ptr相互引用时产生死锁问题的智能指针。如果有两个shared_ptr相互引用,那么这两个shared_ptr指针的引用计数永远不会下降为0,资源永远不会释放。weak_ptr是对对象的一种弱引用,它不会增加对象的use_count,weak_ptr和shared_ptr可以相互转化,shared_ptr可以直接赋值给weak_ptr,weak_ptr也可以通过调用lock函数来获得shared_ptr。

  先看一下两个shared_ptr指针互相引用导致的资源释放失败的例子:

#include <iostream>
#include <memory>
#include <string>
using namespace std; class B;
class A
{
public:
shared_ptr<B> pb_;
~A()
{
cout << "A delete\n";
}
};
class B
{
public:
shared_ptr<A> pa_;
~B()
{
cout << "B delete\n";
}
}; void fun(){
shared_ptr<B> pb(new B());
cout << "pb.use_count " << pb.use_count() << endl;//
shared_ptr<A> pa(new A());
cout << "pa.use_count " << pa.use_count() << endl;// pb->pa_ = pa;
cout << "pb.use_count " << pb.use_count() << endl;//
cout << "pa.use_count " << pa.use_count() << endl;//
pa->pb_ = pb;
cout << "pb.use_count " << pb.use_count() << endl;//2:由于share_ptr是共享资源,所以pb所指向的资源的引用计数也会加1
cout << "pa.use_count " << pa.use_count() << endl;//
}//程序结束时,没有调用A和B的析构函数 void main()
{
fun();
system("pause");
}

  而使用weak_ptr:把A中的shared_ptr<B> pb_改为weak_ptr<B> pb_weak,这样改为了弱引用,传递时不会增加pb引用计数use_count()的值,所以最终能够使A、B资源正常释放:

#include <iostream>
#include <memory>
#include <string>
using namespace std; class B;
class A
{
public:
weak_ptr<B> pb_weak;
~A()
{
cout << "A delete\n";
}
};
class B
{
public:
shared_ptr<A> pa_;
~B()
{
cout << "B delete\n";
}
void print(){
cout << "This is B" << endl;
}
}; void fun(){
shared_ptr<B> pb(new B());
cout << "pb.use_count " << pb.use_count() << endl;//
shared_ptr<A> pa(new A());
cout << "pa.use_count " << pa.use_count() << endl;// pb->pa_ = pa;
cout << "pb.use_count " << pb.use_count() << endl;//
cout << "pa.use_count " << pa.use_count() << endl;// pa->pb_weak = pb;
cout << "pb.use_count " << pb.use_count() << endl;//1:弱引用不会增加所指资源的引用计数use_count()的值
cout << "pa.use_count " << pa.use_count() << endl;// shared_ptr<B> p = pa->pb_weak.lock();
p->print();//不能通过weak_ptr直接访问对象的方法,须先转化为shared_ptr
cout << "pb.use_count " << pb.use_count() << endl;//
cout << "pa.use_count " << pa.use_count() << endl;//
}//函数结束时,正确的情况下,应该调用A和B的析构函数 /*资源B的引用计数一直就只有1,当pb析构时,B的计数减一,变为0,B得到释放,
B释放的同时也会使A的计数减一,同时pa自己析构时也会使资源A的计数减一,那么A的计数为0,A得到释放。
*/ void main()
{
fun();
system("pause");
}

四、unique_ptr

  unique_ptr 是一个独享所有权的智能指针,它提供了严格意义上的所有权。它取代了C++98中的auto_ptr。

用法和auto_ptr类似,详情见一下代码:

#include <iostream>
#include <memory>
#include <string>
using namespace std; unique_ptr<string> fun2(){
return unique_ptr<string>(new string("RUS"));
} void fun(){
unique_ptr<string> pa(new string("CHN"));
//unique_ptr没有use_count()方法
unique_ptr<string> pb(new string("USA")); pb = move(pa);
//p2=p1;//错误,不能直接用等于号
if (pa == nullptr)
cout << "pa现在为空" << endl; cout << "*pb " << *pb << endl;//pb变成了“CHA” string* ps = pb.release();//清空当前智能指针所指的资源对象,并返回指针
cout << "*ps " << *ps << endl;//ps变成了“CHA” pa.reset(ps);//重置指向另一个对象
cout << "*pa " << *pa << endl;//pa变成了“CHA” pb = fun2();//接收函数的返回值可以用等于号,因为使用了移动构造函数
cout << "*pb " << *pb << endl;//pb变成了“RUS”
} void main()
{
fun();
system("pause");
}

C++智能指针 auto_ptr、shared_ptr、weak_ptr和unique_ptr的更多相关文章

  1. 智能指针auto_ptr & shared_ptr

    转载:智能指针auto_ptr 很多人听说过标准auto_ptr智能指针机制,但并不是每个人都天天使用它.这真是个遗憾,因为auto_ptr优雅地解决了C++设计和编码中常见的问题,正确地使用它可以生 ...

  2. C++智能指针: auto_ptr, shared_ptr, unique_ptr, weak_ptr

    本文参考C++智能指针简单剖析 内存泄露 我们知道一个对象(变量)的生命周期结束的时候, 会自动释放掉其占用的内存(例如局部变量在包含它的第一个括号结束的时候自动释放掉内存) int main () ...

  3. C++ 智能指针(shared_ptr/weak_ptr)原理分析

    其主要的类关系如下所示(省略相关的类模板参数): 图1 从上面的类图可以清楚的看出shared_ptr内部含有一个指向被管理对象(managed object)T的指针以及一个__shared_cou ...

  4. C++ | 再探智能指针(shared_ptr 与 weak_ptr)

    上篇博客我们模拟实现了 auto_ptr 智能指针,可我们说 auto_ptr 是一种有缺陷的智能指针,并且在C++11中就已经被摈弃掉了.那么本章我们就来探索 boost库和C++11中的智能指针以 ...

  5. 【C++11新特性】 C++11智能指针之shared_ptr

    C++中的智能指针首先出现在“准”标准库boost中.随着使用的人越来越多,为了让开发人员更方便.更安全的使用动态内存,C++11也引入了智能指针来管理动态对象.在新标准中,主要提供了shared_p ...

  6. C++智能指针之shared_ptr与右值引用(详细)

    1. 介绍 在 C++ 中没有垃圾回收机制,必须自己释放分配的内存,否则就会造成内存泄露.解决这个问题最有效的方法是使用智能指针(smart pointer).智能指针是存储指向动态分配(堆)对象指针 ...

  7. 关于智能指针auto_ptr

    智能指针auto_ptr和shared_ptr也是面试中经常被问到的一个 感觉看auto_ptr的源码反而更加容易理解一些,因为源码的代码量并不大,而且比较容易理解. 本篇主要介绍auto_ptr 其 ...

  8. 【C++智能指针 auto_ptr】

    <More Effective C++>ITEM M9他提到auto_ptr.说是当异常产生的时候.怎么释放为对象分配的堆内存,避免反复编写内存释放语句. PS:这里书里面提到函数退出问题 ...

  9. 智能指针之shared_ptr基本概述

    1.shared_ptr允许有多个指针指向同一个对象,unique_ptr独占所指向的对象. 2.类似于vector,智能指针也是模板.创建智能指针: shared_ptr<string> ...

  10. C++智能指针(auto_ptr)详解

    智能指针(auto_ptr) 这个名字听起来很酷是不是?其实auto_ptr 只是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势,但也有其局限.本文总结的8个问题足 ...

随机推荐

  1. C# File API

    [C# File API] 1.System.IO.File Provides static methods for the creation, copying, deletion, moving, ...

  2. P和C

    import tensorflow as tf import numpy as np import math import keras from keras.layers import Conv2D, ...

  3. 100-days: twenty

    Title: Apple's 'show time(好戏开幕)' event(发布会) puts the spotlight on subscription services Apple's 'sho ...

  4. 使用Spring Cache缓存出现的小失误

    前文:今天在使用Spring Boot项目使用Cache中出现的小失误,那先将自己创建项目的过程摆出来 1.首先创建一个Spring Boot的项目(我这里使用的开发工具是Intellij IDEA) ...

  5. tp3.2 上传文件及下载文件

    公共方法 UploadFile.class.php() // 开始 , , , ,];];,; ;; ::::::;,) {//文件上传失败 //捕获错误代码$this->error($file ...

  6. Python-yield生成器

    1.引入生成器的目的: 通常的for...in...循环中,in后面是一个数组,这个数组就是一个可迭代对象,类似的还有链表,字符串,文件.它可以是mylist = [1, 2, 3],也可以是myli ...

  7. redis常用服务安装部署

    常用服务安装部署   学了前面的Linux基础,想必童鞋们是不是更感兴趣了?接下来就学习常用服务部署吧! 安装环境: centos7 + vmware + xshell 即将登场的是: mysql(m ...

  8. angular ViewChild ContentChild 系列的查询参数

    官方说明 官方文档 在调用 NgAfterViewInit 回调函数之前就会设置这些视图查询. 元数据属性: selector - 用于查询的指令类型或名字. read - 从查询到的元素中读取另一个 ...

  9. c#devexpress 窗体控件dock的重要

    在设计c# devexpress winform 窗体时, 要建立起dock意识, dock就是子窗体如何靠在父窗体上, 有fill 全覆盖, buttom 底部,top 上部... 如下图 pane ...

  10. 一个不错的多叉树, stl风格

    tree<std::string> tr9; tree<std::string>::pre_order_iterator iter1; tr9.set_head("h ...