智能指针是通过引用计数的方式,对指针对象的生命周期进行管理的一种技术方法,它将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象的指针指向同一对象,当此用引用计数为0时,自动释放对象。
每次创建类的新对象时,初始化指针并将引用计数置为1;当对象作为另一对象的副本而创建时,拷贝构造函数拷贝指针并增加与之相应的引用计数;对一个对象进行赋值时,赋值操作符减少左操作数所指对象的引用计数(如果引用计数为减至0,则删除对象),并增加右操作数所指对象的引用计数;调用析构函数时,析构函数减少引用计数(如果引用计数减至0,则删除基础对象)。
Teacher.h
#pragma once
class CTeacher
{
public:
CTeacher();
~CTeacher();
public:
void SetName(const char* szName);
void SetAge(int age);
void Print();
public:
char m_szName[20];
int m_iAge;
};
Teacher.cpp
#include<iostream>
#include<string>
#include "Teacher.h"
using namespace std;
CTeacher::CTeacher():m_iAge(0)
{
memset(m_szName,0,20);
m_iAge = 0;
}
CTeacher::~CTeacher()
{
}
void CTeacher::SetName(const char* szName)
{
if (szName)
{
strcpy_s(m_szName,szName);
}
}
void CTeacher::SetAge(int iAge)
{
m_iAge = iAge;
}
void CTeacher::Print()
{
cout << "姓名:" << m_szName << endl;
cout << "年龄: " << m_iAge << endl;
}
SmartPtr.h
#pragma once
//智能指针类模板
template<typename T>
class SmartPtr
{
public:
SmartPtr() :_ptr(new T()), _ref(new int(1)) //成员变量初始化
{
//默认构造函数
}
SmartPtr(T* p) :_ptr(p), _ref(new int(1))
{
//拷贝构造函数,因为我们这个指针是第一次引用
}
/*SmartPtr(const SmartPtr& sptr) :_ptr(sptr._ptr), _ref(sptr._ref)
{
//拷贝构造函数
++(*_ref); //引用计数+1, 前++比后++效率更高
}*/
~SmartPtr()
{
if (-- (* _ref) == 0)
{
//如果引用计数变为0,释放指针
delete _ptr;
delete _ref;
}
}
public:
//当运算符重载为成员函数时,第一个操作数(左操作数)通过this指针隐式传递
T* operator->()
{ //重载操作符->
return _ptr;
}
T& operator*()
{
//重载操作符*
return *_ptr;
}
SmartPtr& operator=(SmartPtr& inst) //重载操作符 =
{
++inst->_ref; //引用计数+1
if (--(*_ref) == 0)
{
//如果原本的引用计数为0,释放原本的指针
delete _ptr;
delete _ref;
}
_ptr = inst._ptr;
_ref = inst._ref;
return *this;
}
private:
int* _ref; //引用计数
T* _ptr; //要管理的对象指针
};
SmartPtr.cpp
#include<iostream>
#include "Teacher.h"
#include "SmartPtr.h"
using namespace std;
int main()
{
SmartPtr<CTeacher> teacher1; //默认构造new delete
teacher1->SetName("Uncle");
teacher1->SetAge(34);
(*teacher1).Print();
system("pause");
return 0;
}