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;
}

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

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

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

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • pycharm2021激活码【注册码】

    pycharm2021激活码【注册码】,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月20日
    65
  • 有没有支持5V输入和9V输入给两串8.4V锂电池充电的芯片IC「建议收藏」

    有没有支持5V输入和9V输入给两串8.4V锂电池充电的芯片IC「建议收藏」有的FS4062支持5V和9V同步升降压充电8.4V两床锂电池,也就是5V9V适配器自动识别两串8.4V锂电池高效充电管理芯片概述:FS4062是一款宽电压输入,专门为7.4V双节锂电池充电的充电管理芯片,兼容5V,9V适配器。在5V供电的情况下,实现升压充电,电池端最大充电电流1.3A,在9V供电的情况下,实现降压充电,电池端最大充电电流1.2A,充电电流可以通过外置电阻RSET来设定。低阻抗的电源通路可以使充电效率更高,减少充电时间,提高电池使用寿命。.

    2022年10月6日
    4
  • 搭建DNS服务器的那些知识「建议收藏」

    搭建DNS服务器的那些知识「建议收藏」一、DNS服务概述:1.什么是DNS?DNS(DomainNameSystem)域名系统,在TCP/IP网络中有非常重要的地位,能够提供域名与IP地址的解析服务,而不用去记住能够被机器直接读取的IP数串。通过域名,最终得到该域名对应的IP地址的过程叫做域名解析。DNS协议运行在UDP协议之上,使用端口53号。2.什么是域、域名?域(domain)是计算机网络的一种形式,其中所有用户账户,计算机,打印机和其他安全主体都在位于称为域控制器的一个或多个中央计算机集群上的中央数据库中注册。

    2025年9月16日
    4
  • Java webservice详解「建议收藏」

    Java webservice详解「建议收藏」Javawebservice详解1webservice概述2webservice核心要素2.1SOAP2.2WSDL3webservice的使用场景4webservice的结构5Java中的webservice5.1webservice服务端5.2webservice客户端6WDSL文件说明7webservice请求与响应监控7webservice在Tomcat中发布…

    2022年7月13日
    17
  • Nginx 配置 HTTPS 完整过程[通俗易懂]

    Nginx 配置 HTTPS 完整过程[通俗易懂]配置站点使用https,并且将http重定向至https。1.nginx的ssl模块安装查看nginx是否安装http_ssl_module模块。$/usr/local/nginx/sbin/nginx-V![在这里插入图片描述](https://img-blog.csdnimg.cn/2018112610054317.png)如果出现configure…

    2022年7月14日
    15
  • pycharm2022.01.13专业版激活码【2022免费激活】

    (pycharm2022.01.13专业版激活码)最近有小伙伴私信我,问我这边有没有免费的intellijIdea的激活码,然后我将全栈君台教程分享给他了。激活成功之后他一直表示感谢,哈哈~IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html…

    2022年3月31日
    106

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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