【数据结构学习之完全从零实现所有数据结构的代码编写之二】智能指针

今天我们依然暂时不讲解数据结构里面的内容,我们来复习一下昨天学的模板技术用于数据结构编程的思想,给出一个模板技术的实例:智能指针的应用。喜欢看我分享的加我q:1126137994 加我共同学习交流各种技术。

为什么会引入智能指针呢?原因是在软件开发中最可恨最常见的BUG:内存泄漏!是什么导致内存泄漏?

-动态申请堆空间,用完后不归还
-C++语言中,没有垃圾回收机制
-指针无法控制堆空间的生命周期

那么引入智能指针后,智能指针能做什么呢?

-指针生命周期结束时,主动释放堆空间
-一片堆空间,最多只能由一个指针标识
-杜绝指针运算和指针比较

智能指针的设计方案:
-通过类模板描述指针的行为
*能够定义不同类型的指针对象
-重载指针特征操作符(->和*)
*利用对象模拟原生指针的行为

重要说明:智能指针只能用来指向堆空间中的单个对象或者变量

下面给出代码示例,我主要做的是在QT编译器中建立了一个C++工程库,以后所有的数据结构的代码,都在这个库里实现:
头文件(SmartPointer.h):

#ifndef SMARTPOINTER_H
#define SMARTPOINTER_Hnamespace 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对象所对应的申请的堆空间。

那么我们将注释掉的那几行加上,编译运行:
运行结果2
可以看出,sp这个指针已经为空,nsp指针不为空,指向的是Test对象所对应的的堆空间,最后又将这个Test对象析构,销毁堆空间。
当然如果我们在main函数里加上一个nsp++的运算,编译就会报错,因为我们已经禁止了智能指针的比较与运算。

那么到此为此,我们已经实现了智能指针的实例。

总结:
1.指针特征操作符(->和*)可以被重载
2.重载指针特征符能够使用对象代替指针
3.智能指针只能用于指向堆空间中的指针
4.智能指针的意义在于最大程度的避免内存问题

想一起探讨以及获得各种学习资源加我(有我博客中写的代码的原稿):
qq:1126137994
微信:liu1126137994
可以共同交流关于嵌入式,操作系统,C++语言,C语言,数据结构等技术问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/423297.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

职责链模式(Chain of Responsibility)

重要概念 1. 使多个对象都有机会处理请求&#xff0c;从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链&#xff0c;并沿着这条链传递该请求&#xff0c;直到有一个对象处理它为止。 2.请求是沿着链条传递到有一个处理点对象负责处理这个请求为止。请求者无需…

Linux网络-数据包的接收流程(基于RTL8139网卡驱动程序)

本文将介绍Linux系统中&#xff0c;基于RTL8139网卡驱动程序&#xff0c;是如何一步一步将接收到的数据包传送到内核的网络协议栈的。 下图展示了数据包&#xff08;packet&#xff09;如何进入内存&#xff0c;并被内核的网络模块开始处理&#xff1a; -----| | …

mootools

$();// 选择ID为”body_wrap“的元素$(body_wrap);.getElement();// 选择ID为”body_wrap“的元素下面的第一个链接$(body_wrap).getElement(a); or #xxx or .xxx.getElements();// 选择ID为”body_wrap“的元素下面的所有链接$(body_wrap).getElements(a); $(body_wrap).getE…

图形化界面客户端连接phoenix操作hbase

下载客户端软件 DBeaver https://dbeaver.io/download/ 选择对应系统的版本&#xff0c;我这里选择解压版windows64位 创建连接 注意&#xff1a;URL模板就不要一般是默认 选择合适的版本&#xff08;跟你服务器的版本一致&#xff09;&#xff0c;下载jar包 点击测试或完成即…

【C++深度剖析教程12】数组操作符的重载

之前写的C学习记录忘记打编号了&#xff0c;从今天开始&#xff0c;所有内容&#xff0c;记录编号&#xff0c;方便以后的查阅复习。今天学习的是C中&#xff0c;数组操作符的重载。 上一篇博文写的是介绍C中的字符串类&#xff0c;我们知道&#xff0c;C标准库中通过string类…

前端学习(80):按类型划分标签(inline)

解决font-size中间有间隙 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv"X-UA-Compat…

将应用程序安装为Windows服务

将应用程序安装为Windows服务 安装为服务的好处:不用登陆系统就可以自动启动. 微软官方对该小工具的说明&#xff1a;Installs and uninstalls executable services and assigns names to them. 显而易见&#xff0c;这个小工具是用以安装和卸载可执行的服务和指派服务名给这些…

HBase shell 命令介绍

HBase shell是HBase的一套命令行工具&#xff0c;类似传统数据中的sql概念&#xff0c;可以使用shell命令来查询HBase中数据的详细情况。安装完HBase之后&#xff0c;如果配置了HBase的环境变量&#xff0c;只要在shell中执行hbase shell就可以进入命令行界面&#xff0c;HBase…

【C++深度剖析教程13】函数对象的分析

今天来学习函数对象。什么是函数对象呢&#xff1f;下面我们以一个例子来引出函数对象的概念。 假设我们需要编写一个函数&#xff0c;实现下面这些功能&#xff1a; -函数可以获得斐波那契数列每一项的值 -每调用一次返回一个值 -函数可根据需要重复用使用 实现上面的几个…

IE图标消失 HTML文件图标变为未知图标的解决方法

有时候保存在硬盘里的HTM和HTML文件图标会突然变为未知的图标&#xff0c;而且它们往往还是与IE关联&#xff0c;也没有发现病毒。原因我怎么也弄不明白&#xff0c;但可以通过对注册表做些修改来恢复&#xff0c;详细步骤如下: 1.首先打开注册表编辑器&#xff0c;定位到HKEY_…

(SQuirreL SQL Client 客户端 )使用Apache Phoenix 实现 SQL 操作HBase

Apache Phoenix 相信大家并不陌生&#xff0c;它是HBase的SQL驱动&#xff0c;Phoenix 使得Hbase 支持通过JDBC的方式进行访问&#xff0c;并将你的SQL查询转换成Hbase的扫描和相应的动作。 兼容性&#xff1a; Phoenix 2.x - HBase 0.94.x Phoenix 3.x - HBase 0.94.x Phoen…

【C++深度剖析教程14】经典问题解析三之关于赋值的疑问

今天我们来总结一下&#xff0c;之前所学C中所遇到的一些经典的问题。 第一个疑问是&#xff1a; -什么时候需要重载赋值操作符 -编译器是否提供默认的赋值操作&#xff1f; 解答&#xff1a; *编译器为每个类默认重载了赋值操作符 *默认的赋值操作符仅完成了浅拷贝 *当…

微服务架构和SOA的区别

1. 2. 4 微服 务 架构 与 SOA 的 区别 1. 3. 1 微 服务 的 拆分 对于 一般 的 公司 而言&#xff0c; 实践 微 服务 有 非常 大的 技术 挑战&#xff0c; 所以 并不是 所有 的 公司 都 适合 将 单体 架构 拆分 成 微服 务 架构。 一般来说&#xff0c; 微服 务 架构 比较 适合 …

【C++深度剖析教程15】经典问题解析之关于string的疑问

今天来看一下在面试笔试中经常会出错的地方。 我们先来看一个代码&#xff1a; #include <iostream> #include <string>using namespace std;int main() {string s "12345";const char* p s.c_str();cout << p << endl; s.append(&qu…

由于这台计算机没有终端服务器客户端访问许可证,远程会话被中断解决办法...

由于这台计算机没有终端服务器客户端访问许可证&#xff0c;远程会话被中断。 最近在远程连接到一台服务器突然出现这个错误&#xff0c;发现是服务器配置参数错误。安装的时候终端服务器授权模式为“每设备”&#xff0c;那么只要把终端服务器授权模式从“每设备”更改为“每用…

前端学习(83):按显示进行分类

替换元素有自己的特性&#xff0c;虽然属于inline&#xff0c;但是能改变大小

【C++深度剖析教程16】智能指针的分析

今天我们来学习C中的一个独有的特性&#xff0c;智能指针。智能指针的作用非常的强大&#xff0c;它解决了C语言关于指针部分内存泄漏的BUG。那么在此处&#xff0c;内存泄漏指的是什么呢&#xff1f; -动态申请堆空间&#xff0c;用完后不归还 -C语言中没有垃圾回收机制 -指…

【移植Linux 3.4.2内核第三步】从0制作支持新内核的文件系统

学习交流加 个人qq&#xff1a; 1126137994个人微信&#xff1a; liu1126137994学习交流资源分享qq群&#xff1a; 962535112 上一篇文章&#xff0c;我们修改了内核代码改了系统的分区&#xff0c;但是最后启动&#xff0c;发现虽然我们可以挂载之前的文件系统&#xff0c;但是…

回顾2009,展望2010

今天1月2号&#xff0c;更确切的说&#xff0c;是2010年1月2号&#xff0c;刚吃完午饭&#xff0c;突然有一股想写博客的冲动&#xff0c;不为别的&#xff0c;只为祭奠我那逝去的2009&#xff0c;再也回不来的2009。也为了能让自己在2010年有所期盼&#xff0c;有所追求&#…