SharedPointer.h
#ifndef SHAREDPOINTER_H
#define SHAREDPOINTER_H
#include <cstdlib>
#include "Pointer.h"
#include "Exception.h"
// --> 计数变量和堆中的对象,生命周期相同, 都是在堆空间中,两者相关联
namespace DTLib
{
template <typename T>
class SharedPointer : public Pointer<T>
{
protected:
int* m_ref; // 指针要指向堆空间中创建出来的计数变量
void assign(const SharedPointer<T>& obj) // 用于拷贝构造函数
{
this->m_ref = obj.m_ref; // 将当前SharedPointer对象的m_ref成员指针指向了对应着的计数变量
this->m_pointer = obj.m_pointer; // 将当前SharedPointer对象的m_ref成员指针指向了对应着的堆内存
if(this->m_ref) // 使用了计数机制,计数变量要加1
{
(*this->m_ref)++;
}
}
public:
SharedPointer(T* p = NULL) : m_ref(NULL)
{
if(p != NULL)
{
this->m_ref = reinterpret_cast<int*>(std::malloc(sizeof(int))); // 在堆空间中创建一个计数变量
// malloc 返回值是void* ,因此要做强制类型转换
if(this->m_ref )
{
*(this->m_ref) = 1; // 意味着,参数指针p 所指向的堆空间,已经有了一个SharedPointer智能指针对象来指向了
this->m_pointer = p; // 用this->m_pointer成员指针,指向参数指针p所对应着的堆空间
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException, "no enough to create m_ref Object");
}
}
}
SharedPointer(const SharedPointer<T>& obj) : Pointer<T>(NULL)
{
assign(obj);
}
SharedPointer<T>& operator=(const SharedPointer<T>& obj)
{
if(this != &obj)
{
clear(); // 也许当前的智能指针对象,已经指向另一片堆空间了,赋值之前,应将当前的智能指针对象置空
// 先让它不再指向任何的堆空间
assign(obj);
}
return *this;
}
void clear()
{
T* toDel = this->m_pointer; //
int* ref = this->m_ref;
this->m_pointer = NULL;
this->m_ref = NULL;
if(ref) // 一定要关注计数机制,判断一下有无合法的计数变量
{
(*ref)--; // 对象不指向堆空间了,堆空间关联的计数变量-1,
if((*ref) == 0) // 计数变量关联的堆空间已没有任何对象指向了,然后再释放;
{
free(ref);
delete toDel;
}
}
}
~SharedPointer()
{
clear();
}
};
template < typename T > // 通过全局函数的方式来重载
bool operator == (const SharedPointer<T>& l, const SharedPointer<T>& r)
{
return (l.get() == r.get()); // 此处有报错,原因:get()不是const函数,get() 和isNull() 加const就行
} // 两个指针操作符 需要重载
template <typename T>
bool operator!=(const SharedPointer<T>& l, const SharedPointer<T>& r)
{
return (!(l == r)); // 不相等重载 使用 相等重载 来实现
}
}
#endif // SHAREDPOINTER_H
/*
多个对象指向同一片堆空间,还能够自动释放
智能指针的比较
由于SharedPointer支持多个对象同时指向一片堆空间,因此必须支持比较操作
只有这样才能最大程度的模拟原生指针的行为。
*/
Pointer.h
#ifndef POINTER_H
#define POINTER_H
#include "Object.h"
namespace DTLib
{
template < typename T >
class Pointer : public Object
{
protected:
T* m_pointer;
public:
Pointer(T* pointer = NULL)
{
m_pointer = pointer;
}
T* operator -> ()
{
return m_pointer;
}
T& operator * ()
{
return *m_pointer;
}
const T* operator -> () const // 重载函数
{
return m_pointer;
}
const T& operator * () const
{
return *m_pointer;
}
bool isNull() const
{
return( m_pointer == NULL );
}
T* get() const
{
return m_pointer;
}
};
}
#endif // POINTER_H
main.cpp
#include <iostream>
#include "SharedPointer.h"
using namespace std;
using namespace DTLib;
class Test : public Object
{
public:
int value;
Test() : value(0)
{
cout << "Test" <<endl;
}
~Test()
{
cout << "~Test" <<endl;
}
};
int main()
{
/*测验一
SharedPointer<Test> sp0 = new Test();
SharedPointer<Test> sp1 = sp0;
SharedPointer<Test> sp2 = NULL;
sp2 = sp1; // 三个指针指向同一片空间
sp2->value = 100;
cout << sp0->value << endl;
cout << sp1->value << endl;
cout << sp2->value << endl;
sp2.clear();
cout << (sp0 == sp2) << endl;
*/
/* 测试二: */
const SharedPointer<Test> sp0 = new Test();
sp0->value = 100;
return 0;
}