c++ smart pointer
智能指针(smart pointer)是存储指向动态分配(堆)对象指针的类,用于生存期控制,能够确保自动正确的销毁动态分配的对象,防止内存泄露。它的一种通用实现技术是使用引用计数(reference count)。智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象共享同一指针。每次创建类的新对象时,初始化指针并将引用计数置为1;当对象作为另一对象的副本而创建时,拷贝构造函数拷贝指针并增加与之相应的引用计数;对一个对象进行赋值时,赋值操作符减少左操作数所指对象的引用计数(如果引用计数为减至0,则删除对象),并增加右操作数所指对象的引用计数;调用析构函数时,构造函数减少引用计数(如果引用计数减至0,则删除基础对象)。
智能指针就是模拟指针动作的类。所有的智能指针都会重载 -> 和 * 操作符。智能指针还有许多其他功能,比较有用的是自动销毁。这主要是利用栈对象的有限作用域以及临时对象(有限作用域实现)析构函数释放内存。当然,智能指针还不止这些,还包括复制时可以修改源对象等。智能指针根据需求不同,设计也不同(写时复制,赋值即释放对象拥有权限、引用计数等,控制权转移等)。auto_ptr 即是一种常见的智能指针。
智能指针通常用类模板实现:
template <class T>
class smartpointer
{
private:
T *_ptr;
public:
smartpointer(T *p) : _ptr(p) //构造函数
{
}
T& operator *() //重载*操作符
{
return *_ptr;
}
T* operator ->() //重载->操作符
{
return _ptr;
}
~smartpointer() //析构函数
{
delete _ptr;
}
};
下面我们定义一个Person类:
class Person
{
int age;
char* pName; public:
Person(): pName(),age()
{
}
Person(char* pName, int age): pName(pName), age(age)
{
}
~Person()
{
} void Display()
{
printf("Name = %s Age = %d \n", pName, age);
}
void Shout()
{
printf("Ooooooooooooooooo",);
}
};
这么调用:
void main()
{
SP<PERSON> p(new Person("Scott", 25));
p->Display();
{
SP<PERSON> q = p;
q->Display();
// Destructor of Q will be called here..
}
p->Display();
}
Look what happens here.p
andq
are referring to the samePerson
class pointer. Now whenq
goes out of scope, the destructor ofq
will be called which deletes thePerson
class pointer. Now we cannot callp->Display();
sincep
will be left with a dangling pointer and this call will fail. (Note that this problem would have existed even if we were using normal pointers instead of smart pointers.) We should not delete thePerson
class pointer unless no body is using it. How do we do that? Implementing a reference counting mechanism in our smart pointer class will solve this problem. What we are going to do is we will have a reference counting classRC
. This class will maintain an integer value which represents the reference count. We will have methods to increment and decrement the reference count.
我们写一个RC类:
class RC
{
private:
int count; // Reference count public:
void AddRef()
{
// Increment the reference count
count++;
} int Release()
{
// Decrement the reference count and
// return the reference count.
return --count;
}
Now that we have a reference counting class, we will introduce this to our smart pointer class. We will maintain a pointer to class RC
in our SP
class and this pointer will be shared for all instances of the smart pointer which refers to the same pointer. For this to happen, we need to have an assignment operator and copy constructor in our SP
class.
template < typename T > class SP
{
private:
T* pData; // pointer
RC* reference; // Reference count public:
SP() : pData(), reference()
{
// Create a new reference
reference = new RC();
// Increment the reference count
reference->AddRef();
} SP(T* pValue) : pData(pValue), reference()
{
// Create a new reference
reference = new RC();
// Increment the reference count
reference->AddRef();
} SP(const SP<T>& sp) : pData(sp.pData), reference(sp.reference)
{
// Copy constructor
// Copy the data and reference pointer
// and increment the reference count
reference->AddRef();
} ~SP()
{
// Destructor
// Decrement the reference count
// if reference become zero delete the data
if(reference->Release() == )
{
delete pData;
delete reference;
}
} T& operator* ()
{
return *pData;
} T* operator-> ()
{
return pData;
} SP<T>& operator = (const SP<T>& sp)
{
// Assignment operator
if (this != &sp) // Avoid self assignment
{
// Decrement the old reference count
// if reference become zero delete the old data
if(reference->Release() == )
{
delete pData;
delete reference;
} // Copy the data and reference pointer
// and increment the reference count
pData = sp.pData;
reference = sp.reference;
reference->AddRef();
}
return *this;
}
};
客户端调用:
void main()
{
SP<PERSON> p(new Person("Scott", ));
p->Display();
{
SP<PERSON> q = p;
q->Display();
// Destructor of q will be called here.. SP<PERSON> r;
r = p;
r->Display();
// Destructor of r will be called here..
}
p->Display();
// Destructor of p will be called here
// and person pointer will be deleted
}
When we create a smart pointer p
of type Person
, the constructor of SP
will be called, the data will be stored, and a new RC
pointer will be created. The AddRef
method of RC
is called to increment the reference count to 1. Now SP q = p;
will create a new smart pointer q
using the copy constructor. Here the data will be copied and the reference will again be incremented to 2. Now r = p;
will call the assignment operator to assign the value of p
to q
. Here also we copy the data and increment the reference count, thus making the count 3. When r
and q
go out of scope, the destructors of the respective objects will be called. Here the reference count will be decremented, but data will not be deleted unless the reference count becomes zero. This happens only when the destructor of p
is called. Hence our data will be deleted only when no body is referring to it.
上面的参考了http://www.codeproject.com/Articles/15351/Implementing-a-simple-smart-pointer-in-c
这篇文章。
http://zh.wikipedia.org/wiki/%E6%99%BA%E8%83%BD%E6%8C%87%E9%92%88
http://www.informit.com/articles/article.aspx?p=25264
http://ootips.org/yonat/4dev/smart-pointers.html
http://stackoverflow.com/questions/22585974/smart-pointer-implementation
http://stackoverflow.com/questions/106508/what-is-a-smart-pointer-and-when-should-i-use-one
另一篇比较好的文章:
http://blog.csdn.net/hackbuteer1/article/details/7561235
c++ smart pointer的更多相关文章
- [CareerCup] 13.8 Smart Pointer 智能指针
13.8 Write a smart pointer class. A smart pointer is a data type, usually implemented with templates ...
- 理解smart pointer之三:unique_ptr
unique_ptr最先在boost中被定义,后来被C++标准委员会选中为C++11的feature之一. std::unique_ptr is a smart pointer that retain ...
- Why do we need smart pointer and how to implement it.
Here are two simple questions. Problem A #include <string> include <iostream> using name ...
- c++(smart pointer)
(一)首先对智能指针有一些概念性的了解 **********本部分内容摘自开源中国社区http://my.oschina.net/u/158589/blog/28994******** 1.什么是智能 ...
- c/c++ 标准库 智能指针( smart pointer ) 是啥玩意儿
标准库 智能指针( smart pointer ) 是啥玩意儿 一,为什么有智能指针??? c++程序员需要自己善后自己动态开辟的内存,一旦忘了释放,内存就泄露. 智能指针可以帮助程序员"自 ...
- C++ smart pointer智能指针
在C++中,程序员可以直接操作内存,给编程增加了不少的灵活性.但是灵活性是有代价的,程序员必须负责自己负责释放自己申请的内存,否则就会出现内存泄露.智能指针就是为了解决这个问题而存在的.它和其他指 ...
- Effective C++ Item 17 Store newed objects in smart pointer in standalone statements
If you trying to do multiple things in one statement, you should think carefully abnormal behavior e ...
- Smart pointer 智能指针小总结
Smart pointer line 58之后smart pointer里的计数已经是0,所以会真正释放它引用的对象,调用被引用对象的析构函数.如果继续用指针访问,会出现如下图的内存访问异常.所以说如 ...
- smart pointer
smart pointer是一种abstract data type,它可以模仿指针的行为,而且额外提供了一系列诸如自己主动内存管理.边界检查等特性,这些特性是为了在保证效率的基础上降低因为对指针的不 ...
随机推荐
- centos6.4安装flashcache
FlashCache呢是Facebook技术团队的又一力作,最初是为加速MySQL设计的.Flashcache是在Linux层面的,所以任何受磁盘IO困绕的软件或应用都可以方便的使用.为什么是用于加速 ...
- Qt 学习之路 :文件
文件操作是应用程序必不可少的部分.Qt 作为一个通用开发库,提供了跨平台的文件操作能力.从本章开始,我们来了解下 Qt 的文件以及输入输出的功能,也就是 I/O 系统. Qt 通过QIODevice提 ...
- 11.3 afternoon
迭代40 #include<cstdio> #include<cstring> using namespace std; int n,sum,falg; ],c[]; void ...
- Android开发常见错误类型一览表
这是我的第一个博客,我会一直添加我在Android开发中遇到的错误,用来记录我开发中踩过的那些坑 ------------------------分割线------------------------ ...
- Looper Handler MessageQueue Message 探究
Android消息处理的大致的原理如下: 1.有一个消息队列,可以往队列中添加消息 2.有一个消息循环,可以从消息队列中取出消息 Android系统中这些工作主要由Looper和Handler两个类来 ...
- angularjs modal 嵌套modal的问题
anguarjs中当遇到modal嵌套modal的时候,比如一个modal弹出啦一个modal1,关闭modal1后,modal本身的关闭功能失效,那么需要$modal来生命弹出的modal1并且关闭 ...
- 多线程lock(instance)中instance的选择.
如我的提问:http://bbs.csdn.net/topics/390496351?page=1#post-394837834 拥有类原子功能的类: class ShareState { //原子功 ...
- 如何将硬盘GPT分区转换为MBR分区模式
现在新出的笔记本普遍自带WIN8系统,硬盘分区一般都采用GPT格式,但是包括WIN7及以下的系统都无法安装在GPT格式的硬盘上,因此,如果我们需要安装WIN7系统,需要将硬盘分区从GPT转换成MBR格 ...
- AppStore上架规则
1. 条款和条件1.1 为App Store开发程序,开发者必须遵守 Program License Agreement (PLA).人机交互指南(HIG)以及开发者和苹果签订的任何协议和合同.以下规 ...
- 在模型中获取网络数据,刷新tableView
model .h #import <Foundation/Foundation.h> #import "AFHTTPRequestOperationManager.h" ...