C++在设计和使用智能指针

C++在设计和使用智能指针

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

为一个C++用户的。使用指针可以算的上是常态,但在使用过程中。多的时间,可能是由于new要么malloc对象,上次忘记的释放结束(我会犯这样一个错误)。内存泄露。

而此时智能指针可能能够帮助我去解决问题。

智能指针(smart pointer)是利用个引用计数的策略去处理指针的释放,从而保证指针的安全性。

通常情况下,我们会自己去设计一个智能指针类去管理自己的指针对象。

事实上其原理是存储指向动态分配的指针对象类。通过引用计数的功能去控制,去正确的实现指针对象的销毁,从而避免内存泄露。

智能指针的原理是。通过将指针类和一个引用计数关联起来,而引用计数计算,当前指针被多少个对象所共享。

每次创建一个新的指针对象的时候,初始化指针并将引用计数置为1;当对象作为还有一个对象的副本而被创建的时候。拷贝构造函数拷贝指针并添加与之相应的引用计数。对于一个对象进行赋值时。赋值操作符降低左操作数所指对象的引用计数(假设引用计数为减至0,则删除对象),而且添加右操作数所指对象的引用计数;调用析构函数时。构造函数降低引用计数(假设引用计数减至0,删除基础对象)。

以下的代码主要是借鉴了百度百科的代码来学习智能指针:

#include<iostream>
#include<stdexcept>
using namespace std;
#define TEST_SMARTPTR
class Stub
{
public:
	void print(){
		cout<<"Stub:print"<<endl;
	}
	~Stub(){
		cout<<"Stub:Destructor"<<endl;
	}
};
template<typename T>
class SmartPtr
{
public:
	SmartPtr(T*p=0):ptr(p),pUse(new size_t(1)){}
	SmartPtr(const SmartPtr& src):ptr(src.ptr),pUse(src.pUse){
		++*pUse;
	}
	SmartPtr&operator=(const SmartPtr& rhs){
		//self-assigningisalsoright
		++*rhs.pUse;
		decrUse();
		ptr=rhs.ptr;
		pUse=rhs.pUse;
		return *this;
	}
	T* operator->(){
		if(ptr)
			return ptr;
		throw std::runtime_error("accessthroughNULLpointer");
	}
	const T* operator->()const{
		if(ptr)
			return ptr;
		throw std::runtime_error("accessthroughNULLpointer");
	}
	T &operator*(){
		if(ptr)
			return *ptr;
		throw std::runtime_error("dereferenceofNULLpointer");
	}
	const T &operator*()const{
		if(ptr)
			return *ptr;
		throw std::runtime_error("dereferenceofNULLpointer");
	}
	~SmartPtr(){
		decrUse();
#ifdef TEST_SMARTPTR
		std::cout<<"SmartPtr:Destructor"<<std::endl;//fortesting
#endif
	}
private:
	void decrUse(){
		if(--*pUse==0){
			delete ptr;
			delete pUse;
		}
	}
	T* ptr;
	size_t* pUse;
};
int main()
{
	try{
		SmartPtr<Stub> t;
		t->print();
	}catch(const exception&err){
		cout<<err.what()<<endl;
	}
	SmartPtr<Stub>t1(new Stub);
	SmartPtr<Stub>t2(t1);
	SmartPtr<Stub>t3(new Stub);
	t3=t2;
	t1->print();
	(*t3).print();
	return 0;
}

在面的代码中,智能指针一般都会去重载->和*操作符,从而使其表现指针的表象,而且大家能够使用它像使用指针一样。

在函数析构的时候,我们会发现引用计数在当中所起到的作用,从而避免误操作早成指针提前释放。造成指针悬挂。或者释放不彻底,造成内存泄漏的问题。

版权声明:本文博客原创文章。博客,未经同意,不得转载。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/117259.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 数组截取splice_splice返回值

    数组截取splice_splice返回值Javascript数组的splice方法介绍splice()方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。语法格式array.splice(start[,deleteCount[,item1[,item2[,…]]]])参数start必选指定修改的开始位置(从0计数)。如果超出了数组的长度,则从数组末尾开始添加内容;如果是负值,则表示从数组末位开始的第几位(从-1计数,这意味着-n是倒数第n个元素并且等价于

  • spring boot 系列之五:spring boot 通过devtools进行热部署

    前面已经分享过四篇随笔:在上述代码操作的过程中肯定也发现了一个问题:哪怕是一个个小小的修改,都必须要重新启动服务才能使修改生效。那能不能通过配置实现springboot的热部署呢?答案是肯定的。

  • 图卷积网络 GCN Graph Convolutional Network(谱域GCN)的理解和详细推导[通俗易懂]

    图卷积网络 GCN Graph Convolutional Network(谱域GCN)的理解和详细推导[通俗易懂]文章目录1.为什么会出现图卷积神经网络?2.图卷积网络的两种类型2.1vertexdomain(spatialdomain):顶点域(空间域)2.2spectraldomain:频域方法(谱方法)3.什么是拉普拉斯矩阵?3.1常用的几种拉普拉斯矩阵普通形式的拉普拉斯矩阵对称归一化的拉普拉斯矩阵(SymmetricnormalizedLaplacian)随机游走归一化拉普拉斯矩…

  • 常见的十大物联网操作系统介绍(物联网开发技术)

    随着物联网产业的迅猛发展,物联网设备的种类和数量也随之快速增长。据Gartner预测,到2020年全球物联网设备将超过260亿个,物联网市场规模将达到1.9万亿美元。与传统的IT领域不一样,物联网设备分布在各个不同领域,功能和形态各不相同,这对物联网提出了巨大的挑战。嵌入式系统成为关键因素物联网依靠互联网完成信息的传递,嵌入式系统的加入使得信息传递更具有专用性。在物联网出现…

  • ssm管理系统课题_p2实验室

    ssm管理系统课题_p2实验室开发目的方便高效地实验室设备统一管理,除了实现基本的增删改查,还提供借用、归还、购买和问题反馈功能,可实现对实验室设备的基本业务的处理本项目由本人负责开发完成,项目能保证正常运行,当然其中不免也会有缺漏或不完善的地方解决方案1.后端Java框架使用spring+springmvc+mybatisspring功能是实现参数参数注入,请求分发处理,对数据库操作进行事务控制,其中mybatis使用注解查询,整体上大部分使用xml配置,少部分使用注解2.前端使用HTML+javascript+css+j

    2022年10月13日
  • SQL Server中的锁的简单学习

    SQL Server中的锁的简单学习

    2021年11月25日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号