C++智能指针基础知识及其实现
STL中的智能指针简介
先定义一个类
class A {
public:
A(int a) { this->a = a; }
~A() {}
private:
int a;
};
auto_ptr(T*)
现已废弃。
缺点1:多个指针不能指向同一个,以下代码运行时会报错。
A *a = new A(1);
auto_ptr<A> ap1(a);
auto_ptr<A> ap2(a);
缺点2:不能指向数组,以下代码会报错
auto_ptr<int[]> ap (new int[5]{ 1,2,3,4,5 });
缺点3:没有拷贝构造函数。auto_ptr之间不能相互赋值。
unique_ptr(T*)
独占
只能一个指针指向一个
可以指向数组,下面代码是正确的。
unique_ptr<int[]> up (new int[5]{ 1,2,3,4,5 });
指针间相互赋值必须使用move
A *a = new A(1);
unique_ptr<A> ap1(a);
unique_ptr<A> ap2=move(ap1);
cout << ap2->a << endl;
shared_ptr(T*)
可以多个指针共享一个对象
指针之间可以相互赋值
引入了引用计数
A *a = new A(1);
shared_ptr<A> ap1(a);
shared_ptr<A> ap2=ap1;
cout << ap2.use_count() << endl;
输出了ap2的引用计数为2个
weak_ptr(T*)
weak_ptr的引用计数真实反映了shared_ptr的引用计数。
给他赋值之后不用导致引用计数加一
A *a = new A(1);
shared_ptr<A> ap1(a);
shared_ptr<A> ap2=ap1;
weak_ptr<A> wp = ap1;
cout << wp.use_count() << endl;
自己实现一个智能指针
类模板
template<class T>
class SmartPtr{};
成员变量
一个是T类型的指针
template <class T>
class SmartPtr {
private:
T*m_p;
};
构造函数,析构函数
template <class T>
class SmartPtr {
private:
T*m_p;
public:
SmartPtr(T*p = 0);
~SmartPtr();
};
重载->获取T指针,重载*获取T指针的值
template <class T>
class SmartPtr {
public:
T* m_p;
public:
SmartPtr(T*p = 0);
T& operator*();
T* operator->();
~SmartPtr();
};
实现上面这些就实现了一个普通的auto_ptr了。
如果想要实现shared_ptr,增加引用计数的成员变量。
自己实现shared_ptr
新增引用计数成员变量
template <class T>
class SmartPtr {
private:
T* m_p;
size_t * m_Ref;
};
在构造函数中引用计数初始化
template<class T>
SmartPtr<T>::SmartPtr(T*p) {
m_p = p;
m_Ref = new size_t(1);
}
析构函数
当引用计数为0的时候,销毁内存
新增成员函数
void decRef(){
--*m_Ref;
if (*m_Ref == 0) {
delete m_Ref;
delete m_p;
}
}
析构函数实现
template<class T>
SmartPtr<T>::~SmartPtr() {
decRef();
}
拷贝构造函数
两个指向同一块内存,并且引用计数加一
template<class T>
SmartPtr<T>::SmartPtr(const SmartPtr<T>& src) {
m_p = src.m_p;
m_Ref = src.m_Ref;
++*m_Ref;
}
赋值函数
右值引用计数加一
左值引用计数减一
让两个指向同一块内存
template<class T>
SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr<T>& rhs) {
++*rhs.m_Ref;
decRef();
m_p = rhs.m_p;
m_Ref = rhs.m_Ref;
return *this;
}