所谓智能指针就是智能/自动化的管理指针所指向的动态资源的释放。它是一个类,有类似指针的功能,对"和->运算符进行了重载。
常见的智能指针
auto_ptr
特点 :只能有一个智能指旨针占用对象的所有权
示例:
#include "Test.hpp"
#include<memory>
int main(int argc, const char *argv[])
{
auto_ptr<Test> ap(new Test("A"));
ap->show();
auto_ptr<Test> ap2(new Test("B"));
ap2->show();
ap2 = ap ;
cout << "---------" << endl;
ap2->show();
cout << "---------" << endl;
return 0;
}
缺点:
auto_ptr不能赋值和用于初始化另一个对象,如果进行了此类操作,则原智能指针对象无效。
auto_ptr只能管理单个对象,不能管理对象数组。
在C++11标佳中已经废弃auto_ptr 。
unique——ptr
特点:
unique_ptr可以看成是auto_ptr的代替品。因为它对对象的所有权比较专一,所以叫unique。
不允许进行拷贝构造和赋值操作。
允许函数返回unique_ptr类型指针。
支持对象数组。
编译参数:-std=c++11
示例:
#include"Test.hpp"
#include<memory>
int main(int argc, const char *argv[])
{
unique_ptr<Test> up(new Test("hello"));
up->show();
//unique_ptr<Test> up2 = up;//error!
unique_ptr<Test> up2(new Test("world"));
//up2 = up;//error!
up2 = move(up); //转让所有权,up2先释放自己管理的内存,把up管理的内存转让给自己
up.release(); //up释放原来的所有权
up2->show();
cout << "---------" << endl;
unique_ptr<Test[]> up3(new Test[3]);//支持管理数组
return 0;
}
缺点:
无法进行拷贝构造函数和赋值操作
shared_ptr
特点:
shared_ptr定义智能指针A拷贝构造产生智能指针B的时候,A和B共享同一个对象。
shared_ptr定义智能指针A赋值给shared_ptr定义的智能指针B的时候,A和B共享同一个对象。
实现原理:shared_ptr智能惑指针实现的时候,它内部使用了引用计数的技术。。
示例:
#include"Test.hpp"
#include<memory>
int main(int argc, const char *argv[])
{
shared_ptr<Test> sp(new Test("A"));
sp->show();
shared_ptr<Test> sp2 = sp;
sp2->show();
sp->show();
cout << "-------------" << endl;
shared_ptr<Test> sp3(new Test("B"));
sp3 = sp2;
sp3->show();
sp->show();
cout << sp.use_count() << endl;
cout << sp2.use_count() << endl;
cout << sp3.use_count() << endl;
cout << sp.get() << endl;
cout << sp2.get() << endl;
cout << sp3.get() << endl;
return 0;
}
缺点:
循环引用的时候,会带来内存泄漏。
weak_ptr
特点:
weak_ptr是为配合shared_ptr而引入的一种智能指针来协助shared_ptr工作。
weak_ptr的含义为“弱引用”,它的构造和析构不会引起引用计数的增加或减少。
它可以从shared_ptr或另一个weak _ptr产生。
他没有重载"和->,所以不能通过它访问对象内部的成员。
可以使用它提供的lock()获得一个可用的shared_ptr对象。
示例:
#include "Test.hpp"
#include<memory>
int main(int argc, const char *argv[])
{
weak_ptr<Test> obj2;
shared_ptr<Test> obj1(new Test("A"));
obj2 = obj1;
cout << "obj2 count " << obj2.use_count() << endl;
if(!obj2.expired())
{
shared_ptr<Test> obj3 = obj2.lock();
obj3->show();
cout << "obj3 count " << obj3.use_count() << endl;
}
return 0;
}
实现原理总结
1.智能旨针本质上不是指针而是一个类。
⒉智能指针用一个类描述,这个类中有一个指针成员(一个引用计数成员)。
3.智能滑针在栈上创建。
4.构造函数中初始化指针成员指向对象(初始化引用计数成员的值为1)。
5.析构函数中删除指针成员指向的对象(将引用计数的值自减,如果减到0的时候,删除指针成员指向的对象)。
6.对*和->运算符进行了重载.
自定义的shared_ptr智能指针
#ifndef MYSHAREDPTR_H
#define MYSHAREDPTR_H
#include <iostream>
#include <string>
using namespace std;
template <typename T>
class MySharedPtr
{
private:
T* ptr;
long *countRef;
protected:
void release(void)
{
(*countRef) --;
if(*countRef == 0) {
if(ptr != NULL) {
delete ptr;
}
delete countRef;
}
}
public:
explicit MySharedPtr(T* _ptr = NULL) : ptr(_ptr), countRef(new long(1))
{
;//空语句
}
MySharedPtr(const MySharedPtr<T> &other) : ptr(other.ptr), countRef(other.countRef)
{
(*countRef) ++;
}
~MySharedPtr()
{
release();
}
MySharedPtr<T> operator =(const MySharedPtr<T> &other)
{
if(this != &other) {
release();
ptr = other.ptr;
countRef = other.countRef;
(*countRef) ++;
}
}
T& operator *(void)
{
return *ptr;
}
T* operator ->(void)
{
return ptr;
}
T* getPtr(void)
{
return ptr;
}
int getCounRef(void)
{
return *countRef;
}
};
#endif // MYSHAREDPTR_H