智能指针的实现
Posted 每天告诉自己要努力
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了智能指针的实现相关的知识,希望对你有一定的参考价值。
(实现代码做了详细的注释)
内存有四块:全局区、栈区、堆区、代码区
全局区存放着的是等到程序结束前才会释放里面的数据
代码区是存放着编译后的二进制的0和1
栈区:压栈、出栈,会自动管理释放
堆区:new出来的需要手动delete,由程序员管理
而智能指针的实现是利用了栈区和堆区的存储特性来实现的。
一、对象开辟在栈区,析构函数会自动释放内存
class Person{
public:
Person(int age) {
this->m_age = age;
}
~Person() {
cout<<"对象开辟在栈区的话,析构函数会自动释放"<<endl;
}
private:
int m_age;
};
void test1() {
Person p1(10);//这样子创建的对象p1就是存储在栈区的,不用担心内存泄露
}
二、对象开辟在堆区,需要手动delete
class Person{
public:
Person(int age) {
this->m_age = age;
}
~Person() {
cout<<"对象开辟在堆区的话,记得手动释放"<<endl;
}
private:
int m_age;
};
void test1() {
Person *p1 = new Person(10);//这样子创建的对象p1就是存储在堆区,需要手动释放
delete p1; //手动释放
}
三、对象开辟在堆区,利用智能指针可以自动释放
原理简单来说,就是利用栈区会自动释放内存,而堆区不会自动释放内存。所以把不会自动释放内存的东东(new出来的指针),放到可以自动释放内存的东东里面(自定义的智能指针类);
步骤大概如下:(以Person这个自定义类型为例)
①定义一个智能指针的类,用来管理这个开辟在堆区的Person类型指针
②把这个开辟在堆区的Person类型指针,当作智能指针类的有参构造的传入参数
③在栈区创建智能指针类,所以智能指针类会自动执行它的析构函数,因此在智能指针类的析构函数中实现Person类型指针的delete操作,就可以实现自动释放了。
④为了创建一个智能指针对象去模拟这个new出来的Person对象,需要借助运算符重载,模拟出原来的Person指针可以实现的->
和*解引用
操作。
//先构造一个Person类作为例子,让智能指针类管理Person *
class Person {
public:
Person(int age) {
this->m_age = age;
}
void showAge() {
cout << this->m_age << endl;
}
private:
int m_age;
};
//定义智能指针类
class smartPointer{
public:
smartPointer(Person *person) {
this->person = person;
}
//2️⃣智能指针类在栈区,是会自动调用析构的。所以在析构中delete掉需要手动释放的Person*,达到了自动管理的目的。
~smartPointer() {
if (this->person != NULL) {
delete this->person;
this->person = NULL;
}
}
//3️⃣重载-> 模拟sp->showAge(); 等同于person->showAge();
Person* operator->() {
return this->person;
}
//4️⃣重载* 模拟(*sp).showAge(); 等同于(*person).showAge();
Person& operator*() {
return *this->person;
}
private:
Person * person;
};
int main() {
//1️⃣sp作为智能指针,开辟到栈上,自动释放。把new出来的Person*类型作为智能指针类的有参构造的传入参数
smartPointer sp(new Person (10));
//3️⃣模拟sp->showAge(); 等同于person->showAge();在智能指针内部进行了运算符重载
sp->showAge();
//实际上重载了之后,返回的是Person*类型,也就是说sp->是个Person*指针,因此想要调用showAge函数的时候,应该要sp->->showAge();但是编译器给自动做了优化处理了
//4️⃣模拟(*sp).showAge(); 等同于(*person).showAge();在智能指针内部进行了运算符重载
(*sp).showAge();
//重载之后返回的是Person*指针指向的对象本体
return 0;
}
总结
- 如果有new出来的类对象,是需要程序员手动delete释放内存的,为了防止程序员健忘,用智能指针类去管理这个new出来的类对象,实现自动delete释放内存的目的。并且运用运算符重载的功能,实现智能指针对象的调用类对象成员函数的功能,模拟成类对象一样的调用成员函数功能。
以上是关于智能指针的实现的主要内容,如果未能解决你的问题,请参考以下文章
Android系统的智能指针(轻量级指针强指针和弱指针)的实现原理分析
智能指针(模拟实现AutoPtrScopedPtrSharedPtr)