LightRefBase 轻指针的实现原理
前言
本文参考了百问科技韦东山先生C++课程中对于智能指针的讲解,在此基础上根据自己的理解,形成本文。特此说明。
正文中的所有源码可以从Github获取。
https://github.com/musiclspace/LightRefBase_Examples
1. 问题引出:指针的内存泄漏
与Java自带内存回收机制不同,C++使用new方法创建类的对象后,如果不执行delete函数,这个对象会一直保留在内存的HEAP区域,导致内存泄漏。
我们来看一个内存泄漏的简单实例:
首先声明一个类:
//Person.h
#ifndef PERSON_H
#define PERSON_H
#include <iostream>
class Person
{
public:
Person();
~Person();
void showinfo(void);
};
#endif
然后实现这个类
//Person.cpp
#include "Person.h"
using namespace std;
Person::Person()
{
cout << "Person()" << endl;
}
Person::~Person()
{
cout << "~Person()" << endl;
}
void Person::showinfo(void)
{
cout << "showinfo()" << endl;
}
在main.cpp中创建这个类的指针
#include "Person.h"
void test_func(void)
{
Person *p = new Person();
p->showinfo();
}
int main(int argc, char **argv)
{
int i;
for(i = 0; i < 2;i++)
{
test_func();
}
return 0;
}
然后编辑一个Makefile来编译
Person : main.o Person.o
g++ -o $@ $^
%o : %.cpp
g++ -o $@ -c $<
clean :
rm -rf *.o Person
编译后的运行结果为:
Person()
showinfo()
Person()
showinfo()
由此可见调用了两次Person的构造函数来创建对象,但是执行完成后并没有调用类的析构函数。导致内存泄漏。原因是使用new方法创建的对象,位于内存的HEAP区域,而HEAP区域是不会像STACK区域那样结束自动回收的。
2. 解决思路:类的析构
我们需要考虑如何自动回收指针。一个可行的思路是将指向Person的这个指针,定义为另外一个类的数据成员,通过这个类来创建这个指针,这样类被销毁时,利用析构函数将指针回收。
于是我们重新定义一个sp类来实现这个功能
//sp.h
#ifndef SP_H
#define SP_H
#include "Person.h"
class sp
{
Person *p;
public:
sp();
sp