概述
内存泄漏是在动态申请堆空间,用完后不归还。对于 Java 和 C#而言已经有内存回收的机制了。但是对于经典 c++ 而言是没有垃圾回收机制的。 会引起指针无法控制所指堆的空间的生命周期。
设计方案
- 指针生命周期结束时主动释放堆空间
- 一片堆空间最多只能有一个智能指针标识
- 杜绝指针运算和指针比较
- 通过类模板描述指针的行为 ,能够定义不同类型的指针
- 重载指针特征操作符(*和->)利用对象模拟原生指针的行为
代码实现
#ifndef SMARTPOINT_H
#define SMARTPOINT_H
namespace MYLIB
{
template<typename T>
class MySmartPoint{
/*
智能指针实现需要满足的三个需求
1.指针生命周期结束的时候自动释放堆空间
2.一片堆空间最多只能有一个指针标识 拷贝构造函数的实现
3.杜绝指针的运算和比较
*/
protected:
T* my_pointer;
public:
//默认构造函数
MySmartPoint(T*p = NULL)
{
my_pointer = p;
}
//拷贝构造函数
MySmartPoint(const MySmartPoint<T>&obj)
{
my_pointer = obj.my_pointer;
//进行强制转换 const_cast 默认是const是不能转换的
const_cast<MySmartPoint<T>&>(obj).my_pointer = NULL;
}
//进行赋值重载
MySmartPoint<T>& operator=(const MySmartPoint<T>& obj)
{
if(this != &obj )
{
delete my_pointer;
my_pointer = obj.my_pointer;
//进行强制转换 const_cast 默认是const是不能转换的
const_cast<MySmartPoint<T>&>(obj).my_pointer = NULL;
}
return *this;
}
//重载指针的运算操作符
T* operator->()
{
return my_pointer;
}
T& operator*()
{
return *my_pointer;
}
//提供测试用的成员函数
bool isNull()
{
return(NULL == my_pointer);
}
T* get()
{
return my_pointer;
}
//定义析构函数
~MySmartPoint()
{
delete my_pointer;
}
};
}
#endif // SMARTPOINT_H
测试代码:
#include <iostream>
#include"smartpoint.h"
using namespace std;
using namespace MYLIB;
class Test
{
public:
Test()
{
cout<<"test()"<<endl;
}
~Test()
{
cout<<"~test()"<<endl;
}
};
int main()
{
MySmartPoint<Test> sp = new Test();
MySmartPoint<Test> nsp;
nsp = sp;
cout<<nsp.isNull()<<endl;
cout<<sp.isNull()<<endl;
//q++;
return 0;
}
总结
智能指针使用的注意事项:只能用来指向堆空间中的单个对象或者变量。在当前版本的只能指针还是存在一些缺陷的,在后续的文章里面,我会抽空来进行补充。