智能指针的分析
内存泄漏(臭名昭著的Bug)
1、动态申请堆空间,用后不归还;
2、C++语言中没有垃圾回收机制;
3、指针无法控制所指堆空间的生命周期。
内存泄漏的编程实验
#include <stdio.h>
#include <iostream>
#include <cstring>
using namespace std;
class Test
{
int i;
public:
Test()
{
}
Test(int i)
{
this->i = i;
}
int getI()
{
return i;
}
~Test()
{
//delete m_pointer;
}
};
int main()
{
for(int i=0; i<5; i++)
{
Test* p = new Test(i); //会出现内存泄漏
cout << p->getI() << endl;
}
//cout << s << endl;
return 0;
}
思考
我们需要什么?
1、需要一个特殊的指针(通过一个对象来代替一个指针);
2、指针生命周期结束时主动释放堆空间;
3、一片堆空间最多只能由一个指针标识;
4、杜绝指针运算和指针比较。
解决方案
1、重载指针特征操作符(-> 和 *);
2、只能通过类的成员函数重载;
3、重载函数不能使用参数;
4、只能定义一个重载函数。
编程实验:
#include <stdio.h>
#include <iostream>
#include <cstring>
using namespace std;
class Test
{
int i;
public:
Test()
{
}
Test(int i)
{
cout << "Test(int i)" << endl;
this->i = i;
}
int getI()
{
return i;
}
~Test()
{
cout << "~Test()" << endl;
}
};
class Pointer
{
Test* mp;
public:
Pointer(Test* p = NULL)
{
mp = p;
}
Pointer(const Pointer& obj)
{
//delete mp;
mp = obj.mp;
const_cast <Pointer&>(obj).mp = NULL;
}
Pointer& operator = (const Pointer& obj)
{
if(this != &obj)
{
delete mp;
mp = obj.mp;
const_cast <Pointer&>(obj).mp = NULL;
}
return *this;
}
Test* operator ->()
{
return mp;
}
Test& operator *()
{
return *mp;
}
//判断一个指针是否为空
bool isNULL()
{
return(mp == NULL);
}
~Pointer()
{
delete mp;
}
};
int main()
{
Pointer p1 = new Test(0);
cout << p1->getI() << endl;
Pointer p2 = p1;
cout << p1.isNULL() << endl;
cout << p2->getI() << endl;
return 0;
}
智能指针的使用军规
**只能用来使用指向堆空间中的对象或者变量;**
小结
1、指针特征操作符(-> 和 *)可以被重载;
2、重载指针特征操作符能够使用对象代替指针;
3、智能指针只能用于指向堆空间中的内存;
4、智能指针的意义在于最大程度的避免内存的问题。