在微信上看到一篇“C++引用计数及智能指针的简单实现”的好文章点击打开链接,通俗易懂,激起了敲代码的兴趣,于是用两种方式实现了简单的智能指针(辅助类+SmartPtr类 vs SmartPtr类)。关于什么是智能指针以及普通指针所存在的问题以及什么是引用计数,查看该文即可(讲的很好)点击打开链接,本文仅列出两种实现方式的代码,希望对大家有所帮助,若存在问题,欢迎指正,谢谢!
方式一:辅助类+SmartPtr类(实现原理如下图)
#pragma once
#include<iostream>
using namespace std;
//使用辅助类
template<class T>
class SmartPtr;
/*
辅助类包含:
1、引用计数器_count;
2、指向实际空间的指针_ptr;
*/
template<class T>
class Asistant
{
friend class SmartPtr<T>;
private:
Asistant(T *ptr) :_count(1), _ptr(ptr)
{}
~Asistant(){
delete _ptr;
_ptr = NULL;
}
int _count;
T *_ptr;
};
/*
智能指针类:(包含)
1、指向辅助类的指针
*/
template<class T>
class SmartPtr{
public:
SmartPtr(T *ptr) :_p(new Asistant<T>(ptr))
{}
SmartPtr(const SmartPtr<T> &sp){
_p = sp._p;
_p->_count++;
}
SmartPtr& operator=(const SmartPtr<T> &sp){
if (this != &sp){
//处理好原来的关系---->注意:处理好与“前妻”的关系
if (--(_p->_count) == 0){
delete _p; //会先调用辅助类的析构函数(释放实际空间),再释放辅助类对象空间
}
//指向新的辅助空间
_p = sp._p;
(_p->_count)++;
}
return *this;
}
~SmartPtr(){
if (--(_p->_count) == 0){
delete _p;
_p = NULL;
}
}
T* operator->(){
return _p->_ptr;
}
T& operator*(){
return *(_p->_ptr);
}
private:
Asistant<T> *_p;
};
#pragma once
#include<iostream>
using namespace std;
//在一个类中实现智能指针
template<class T>
class SmartPtr1{
public:
SmartPtr1(T *ptr) :_countPtr(new int(1)), _ptr(ptr)
{}
~SmartPtr1(){
if (--(*_countPtr) == 0){
delete _ptr;
delete _countPtr;
_ptr = NULL;
_countPtr = NULL;
}
}
SmartPtr1(const SmartPtr1<T> &sp){
_countPtr = sp._countPtr;
++(*_countPtr);
_ptr = sp._ptr;
}
/*
operator=四部曲:
1、检查自赋值
2、与以前“一刀两断”
3、指向新世界
4、return *this
*/
SmartPtr1& operator=(const SmartPtr1<T> &sp){
if (this != &sp){
if (--(*_countPtr) == 0){
delete _countPtr;
delete _ptr;
_countPtr = NULL;
_ptr = NULL;
}
_countPtr = sp._countPtr;
++(*_countPtr);
_ptr = sp._ptr;
}
return *this;
}
T* operator->(){
return _ptr;
}
T& operator*(){
return *_ptr;
}
private:
int *_countPtr;//指向引用计数的指针
T *_ptr; //指向实际空间的指针
};
测试程序
#include"SmartPtr.h"
#include"SmartPtr1.h"
#include<vld.h> //用于检测内存泄露
//垂悬指针:指向已被释放空间的指针
void HangPtr()
{
int *ptr1 = new int(10);
int *ptr2 = ptr1;
int *ptr3 = ptr1;
cout << "before delete:" << endl;
cout << *ptr1 << endl;
cout << *ptr2 << endl;
cout << *ptr3 << endl;
cout << "after delete:" << endl;
delete ptr1;
cout << *ptr2 << endl;//所指向的空间已被释放--->悬垂指针,程序崩溃“指日可待”
cout << *ptr3 << endl;
}
//SmartPtr
//-------------------> SmartPtr <---------------------------
//测试拷贝构造函数
void test1(){
int *p = new int(10);
SmartPtr<int> sp(p);
{
SmartPtr<int> sp1(sp);
}
SmartPtr<int> sp2(sp);
}
//测试operator=
void test2()
{
int *p = new int(10);
SmartPtr<int> ptr(p);
int *p1 = new int(20);
SmartPtr<int> ptr1(p1);
ptr1 = ptr;
cout << *ptr << endl;
cout << *ptr1 << endl;
}
//-------------------> SmartPtr1 <---------------------------
//测试拷贝构造函数
void test3(){
int *p = new int(10);
SmartPtr1<int> sp(p);
{
SmartPtr1<int> sp1(sp);
}
SmartPtr1<int> sp2(sp);
}
//测试operator=
void test4()
{
int *p = new int(10);
SmartPtr<int> ptr(p);
int *p1 = new int(20);
SmartPtr<int> ptr1(p1);
ptr1 = ptr;
cout << *ptr << endl;
cout << *ptr1 << endl;
}
int main()
{
test4();
system("pause");
return 0;
}