目录
1.内存泄露
当代C++软件平台中的智能指针
- 指针生命周期结束时主动释放堆空间
- 一片堆空间最多只能由一个指针标识
- 杜绝指针运算和指针比较
智能指针的设计方案
通过类模板描述指针的行为
- 能够定义不同类型的指针对象
重载指针特征操作符(->和*)
- 利用对象模拟原生指针的行为
编程实验:智能指针
这个就开始创建库模板了
SmartPointer.h
#ifndef SMARTPOINTER_H
#define SMARTPOINTER_H
//要求1:指针生命周期结束时主动释放堆空间
//1.1创建一个名称空间
namespace JQLib
{
template <typename T>
class SmartPointer
{
protected:
//1.2.定义一个成员变量,就是一个原生指针
T* m_pointer;
public:
//1.3定义公有的成员函数
//1.3.1带参构造函数
SmartPointer(T* p = NULL)
{
//默认情况下将成员变量的值赋值为空
m_pointer = p;
}
//要求2:一片堆空间最多只能由一个指针标识
//2.1就需要提供一个拷贝构造函数
SmartPointer(const SmartPointer<T>& obj)
{
//当前对象的成员指针,指向obj这个参数所指向的堆空间
//这样就有两个指针指向了一个堆空间,不符合要求
m_pointer =obj.m_pointer;
//所以就需要将obj这个对象的成员指针置空
//obj.m_pointer = NULL;//这里obj是const对象,
//所以不能直接赋值,需要进行强制类型的转换,取消const属性
const_cast<SmartPointer<T>&>(obj).m_pointer = NULL;
}
//2.2重载赋值操作符
SmartPointer<T>& operator= (const SmartPointer<T>& obj)
{
//判断是不是自赋值-自己赋值给自己
if(this != &obj)//否
{
//释放成员指针的空间
delete m_pointer;
m_pointer =obj.m_pointer;
const_cast<SmartPointer<T>&>(obj).m_pointer = NULL;
}
//返回自身;意义:可以支持连续的赋值
return *this;
}
//1.3.2重载指针的特征操作符
//重载->
T* operator-> ()
{
//直接返回这个成员指针
return m_pointer;
}
//重载*
T& operator* ()
{
//返回成员指针指向的内容
return *m_pointer;
}
//1.3.3提供两个实用的成员函数
//判断当前的这个指针是否为空指针
bool isNull()
{
return (m_pointer == NULL);
}
//返回成员指针的值
T* get()
{
return m_pointer;
}
//1.3.4.析构函数,主动的释放这个成员指针指向的堆空间
//完成这4步就完成了要求1
~SmartPointer()
{
delete m_pointer;
}
};
}
#endif // SMARTPOINTER_H
main.c
#include <iostream>
#include "SmartPointer.h"
using namespace std;
using namespace JQLib;
//测试JQLib
class Test
{
public:
Test()
{
cout<<"Test()"<<endl;
}
~Test()
{
cout<<"~Test()"<<endl;
}
};
int main()
{
//测试JQLib
//定义一个智能指针,指向堆空间里面的Test对象
//必须说明sp是指向Test地址的
SmartPointer<Test> sp = new Test();//Test()
SmartPointer<Test> nsp;
nsp = sp;
//nsp++;//编译出错,指针不可以++操作
cout<<sp.isNull()<<endl;//1
cout<<nsp.isNull()<<endl;//0
//~Test()
return 0;
}
智能指针的使用军规,只能用来指向堆空间中的单个对象或者变量
2.小结
- 指针特征操作符(->和*)可以被重载
- 重载指针特征符能够使用对象代替指针
- 智能指针只能用于指向堆空间中的内存
- 智能指针的意义在于最大程度的避免内存问题