当前位置: 首页 > news >正文

智能指针的实现

内存有四块:全局区、栈区、堆区、代码区。

全局区存放着的是等到程序结束前才会释放里面的数据

代码区是存放着编译后的二进制的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释放内存的目的。并且运用运算符重载的功能,实现智能指针对象的调用类对象成员函数的功能,模拟成类对象一样的调用成员函数功能。

转自:智能指针的实现_每天告诉自己要努力的博客-CSDN博客_智能指针怎么实现的 

相关文章:

  • 什么是构造函数和析构函数?
  • CD-ROM
  • 光盘文件格式-udf、iso9660、Joliet、Romeo
  • 刻录光盘的程序步骤
  • ISO文件
  • DVD-数字通用光盘
  • VCD-影音光碟
  • CD-CompactDisk
  • 光盘的标准与格式
  • Hash-散列函数
  • 索引(index)是什么
  • QT 中文乱码解决汇总(包括QString与string、char*互转乱码)
  • c++中const的作用
  • C++ const 详解
  • QT之QML
  • Apache Pulsar 2.1 重磅发布
  • JSDuck 与 AngularJS 融合技巧
  • JS函数式编程 数组部分风格 ES6版
  • js继承的实现方法
  • Laravel核心解读--Facades
  • Linux下的乱码问题
  • nginx 配置多 域名 + 多 https
  • yii2权限控制rbac之rule详细讲解
  • 分布式熔断降级平台aegis
  • 记一次用 NodeJs 实现模拟登录的思路
  • 马上搞懂 GeoJSON
  • 如何实现 font-size 的响应式
  • 学习Vue.js的五个小例子
  • 看到一个关于网页设计的文章分享过来!大家看看!
  • 格斗健身潮牌24KiCK获近千万Pre-A轮融资,用户留存高达9个月 ...
  • 哈罗单车融资几十亿元,蚂蚁金服与春华资本加持 ...
  • 没有任何编程基础可以直接学习python语言吗?学会后能够做什么? ...
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • !$boo在php中什么意思,php前戏
  • #AngularJS#$sce.trustAsResourceUrl
  • #vue3 实现前端下载excel文件模板功能
  • (1)常见O(n^2)排序算法解析
  • (2)nginx 安装、启停
  • (Forward) Music Player: From UI Proposal to Code
  • (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画...
  • (全注解开发)学习Spring-MVC的第三天
  • (一) storm的集群安装与配置
  • (转)EXC_BREAKPOINT僵尸错误
  • (转)jdk与jre的区别
  • .gitignore文件---让git自动忽略指定文件
  • .NET CF命令行调试器MDbg入门(四) Attaching to Processes
  • .net FrameWork简介,数组,枚举
  • .NET 自定义中间件 判断是否存在 AllowAnonymousAttribute 特性 来判断是否需要身份验证
  • .netcore 如何获取系统中所有session_ASP.NET Core如何解决分布式Session一致性问题
  • .netcore如何运行环境安装到Linux服务器
  • .NET高级面试指南专题十一【 设计模式介绍,为什么要用设计模式】
  • .NET开发人员必知的八个网站
  • .net连接MySQL的方法
  • .pub是什么文件_Rust 模块和文件 - 「译」
  • @GlobalLock注解作用与原理解析