智能指针的实现:计数
Shared_ptr
- 智能指针自动释放动态内存
- shared_ptr允许多个指针指向同一个对象 每个shared_ptr都有一个计数器
- 当进行拷贝/赋值时计数器进行++ 当被销毁时(例如局部变量超出作用域)计数器-- 当计数器为0时 自动释放内存空间
- .unique bool类型 如果.use_count()为 1,返回true
- .use_count() 返回与该指针共享对象的指针数量 计数器
分析
- 构造函数 传入指针进行初始化
- 析构函数 递减计数器 当计数器为0时 delete 释放内存
- 拷贝构造函数 拷贝时计时器递增
- 赋值操作符 赋值时右操作对象被赋予左操作对象 左对象原计数器-- 右对象计数器++
- 解引用与->返回结果不一样 解引用返回对象引用 ->返回对象指针
缺陷
- 容易造成循环引用 方法使用弱指针 weak_ptr
#include<iostream>
#include <assert.h>
using namespace std;
template<typename T>
class Smart_ptr
{
public:
Smart_ptr(T* ptr);
~Smart_ptr();
Smart_ptr(const Smart_ptr&ptr);
Smart_ptr& operator=(const Smart_ptr & ptr);
T& operator*();
T* operator->();
public:
bool unique() { return (*_count) == 1; };
size_t use_count() { return *_count; };
private:
size_t* _count;
T* _ptr;
};
template<typename T>
Smart_ptr<T>::Smart_ptr(T * ptr) :_ptr(ptr)
{
if (_ptr)
_count = new size_t(1);
else
_count = new size_t(0);
}
template<typename T>
Smart_ptr<T>::~Smart_ptr()
{
(*_count)--;
if (*_count == 0)
{
delete _ptr;
delete _count;
_count = nullptr;
_ptr = nullptr;
}
}
template<typename T>
Smart_ptr<T>::Smart_ptr(const Smart_ptr & ptr)
{
if (_ptr != ptr._ptr)
{
_ptr = ptr._ptr;
_count = ptr._count;
(*_count)++;
}
}
template<typename T>
Smart_ptr<T> & Smart_ptr<T>::operator=(const Smart_ptr & ptr)
{
if (ptr == this->_ptr)
return *this;
if (_ptr)
{
(*_count)--;
_ptr = ptr._ptr;
_count = ptr._count;
(*_count)++;
}
else
{
_ptr = ptr;
_count = ptr._count;
(*_count)++;
}
return *this;
}
template<typename T>
T & Smart_ptr<T>::operator*()
{
assert(_ptr != nullptr);
return (*this->_ptr);
}
template<typename T>
T * Smart_ptr<T>::operator->()
{
assert(_ptr != nullptr);
return this->_ptr;
}
class A
{
public:
A(int value) :_value(value) {};
~A() {};
void AAA()
{
cout << _value << endl;
}
private:
int _value;
};
int main()
{
A *a = new A(10);
A *b = new A(20);
Smart_ptr<A> p1(a);
{
Smart_ptr<A> p2 = p1;
cout << p1.unique() << endl;
cout << p2.unique() << endl;
cout << p1.use_count() << endl;
cout << p2.use_count() << endl;
(*p1).AAA();
(*p2).AAA();
{
Smart_ptr<A> p3(p2);
cout << p3.use_count() << endl;
cout << p1.use_count() << endl;
(*p3).AAA();
}
}
cout << p1.unique() << endl;
cout << p1.use_count() << endl;
}