今天我们依然暂时不讲解数据结构里面的内容,我们来复习一下昨天学的模板技术用于数据结构编程的思想,给出一个模板技术的实例:智能指针的应用。喜欢看我分享的加我q:1126137994 加我共同学习交流各种技术。
为什么会引入智能指针呢?原因是在软件开发中最可恨最常见的BUG:内存泄漏!是什么导致内存泄漏?
-动态申请堆空间,用完后不归还
-C++语言中,没有垃圾回收机制
-指针无法控制堆空间的生命周期
那么引入智能指针后,智能指针能做什么呢?
-指针生命周期结束时,主动释放堆空间
-一片堆空间,最多只能由一个指针标识
-杜绝指针运算和指针比较
智能指针的设计方案:
-通过类模板描述指针的行为
*能够定义不同类型的指针对象
-重载指针特征操作符(->和*)
*利用对象模拟原生指针的行为
重要说明:智能指针只能用来指向堆空间中的单个对象或者变量
下面给出代码示例,我主要做的是在QT编译器中建立了一个C++工程库,以后所有的数据结构的代码,都在这个库里实现:
头文件(SmartPointer.h):
#ifndef SMARTPOINTER_H
#define SMARTPOINTER_H
namespace DTLib
{
template <typename T> //开始泛型编程
class SmartPointer
{
protected:
T* m_pointer; //T类型指针
public:
SmartPointer(T* p = NULL)
{
m_pointer = p; //首先将m_pointer置空
}
SmartPointer(const SmartPointer<T>& obj) //拷贝构造函数,实现一片堆空间只能由一个指针标识
{
m_pointer = obj.m_pointer;
const_cast<SmartPointer<T>&>(obj).m_pointer = NULL;
}
SmartPointer<T>& operator = (const SmartPointer<T>& obj)
{
if (this != &obj) //判断是否自赋值,不能做比较运算,this当前的对象
{
delete m_pointer;
m_pointer = obj.m_pointer;
const_cast<SmartPointer<T>&>(obj).m_pointer = NULL;
}
return *this; //可以支持连续的赋值
}
T* operator-> () //重载->操作符,让T对象可以代表指针m_pointer
{
return m_pointer;
}
T& operator* () //重载*操作符,
{
return *m_pointer;
}
bool isNull() //判断是否销毁指针
{
return (m_pointer == NULL);
}
T* get()
{
return m_pointer;
}
~SmartPointer() //析构函数,很重要,对象的生命周期结束时主动的销毁指针
{
delete m_pointer;
}
};
}
#endif // SMARTPOINTER_H
main.cpp函数:
#include <iostream>
#include "SmartPointer.h"
using namespace std;
using namespace DTLib; //使用我们定义的命名空间
class Test
{
public:
Test()
{
cout << "Test()" << endl; //测试试验,仅打印语句
}
~Test()
{
cout << "~Test()" << endl; //测试试验,仅打印语句
}
};
int main()
{
SmartPointer<Test> sp = new Test(); //声明一个智能指针sp指向Test对象所对应的的堆空间
//SmartPointer<Test> nsp; //又定义了一个智能指针
//nsp = sp; //该智能指针指向sp指向Test对象所对应的的堆空间
//cout << sp.isNull() << endl;
//cout << nsp.isNull() << endl;
return 0;
}
运行上面程序,显示结果为:
可以看出,我们并没有主动去归还申请的堆空间,而是程序自动的调用了析构函数销毁了Test对象所对应的申请的堆空间。
那么我们将注释掉的那几行加上,编译运行:
可以看出,sp这个指针已经为空,nsp指针不为空,指向的是Test对象所对应的的堆空间,最后又将这个Test对象析构,销毁堆空间。
当然如果我们在main函数里加上一个nsp++的运算,编译就会报错,因为我们已经禁止了智能指针的比较与运算。
那么到此为此,我们已经实现了智能指针的实例。
总结:
1.指针特征操作符(->和*)可以被重载
2.重载指针特征符能够使用对象代替指针
3.智能指针只能用于指向堆空间中的指针
4.智能指针的意义在于最大程度的避免内存问题
想一起探讨以及获得各种学习资源加我(有我博客中写的代码的原稿):
qq:1126137994
微信:liu1126137994
可以共同交流关于嵌入式,操作系统,C++语言,C语言,数据结构等技术问题。