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)
上一篇 2022年1月8日 下午3:00
下一篇 2022年1月8日 下午3:00


相关推荐

  • Android 代码设置RelativeLayout元素居中

    Android 代码设置RelativeLayout元素居中RelativeLayoutrelativeLayout=newRelativeLayout(this);RelativeLayout.LayoutParamsrlp=newRelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_C

    2022年7月17日
    16
  • 2分钟教你,速领vidu积分2000-1万,最后10天【方法教程】

    2分钟教你,速领vidu积分2000-1万,最后10天【方法教程】

    2026年3月12日
    3
  • XSS(跨站脚本攻击)详解

    XSS(跨站脚本攻击)详解目录 XSS 的原理和分类 XSS 的攻击载荷 XSS 可以插在哪里 XSS 漏洞的挖掘 XSS 的攻击过程 XSS 漏洞的危害 XSS 漏洞的简单攻击测试反射型 XSS 存储型 XSS DOM 型 XSS XSS 的简单过滤和绕过 XSS 的防御反射型 XSS 的利用姿势 get 型 post 型利用 JS 将用户信息发送给后台 XSS 的原理和分类跨站脚本攻击 XSS Cros

    2026年3月20日
    1
  • kotlin数组和集合

    kotlin数组和集合一 Kotlin 数组 1 对象数组由 Kotlin 的 main 函数的写法 可以看出 Kotlin 中的对象数组写法与泛型的写法很像 funmain args Array lt String gt 声明对象数组的三种形式 1 使用 arrayOf 函数和指定的数组元素创建数组 Java 写法 String params1 str1 str2 str

    2026年3月17日
    2
  • 直通线和交叉线[通俗易懂]

    直通线和交叉线[通俗易懂]感觉这个问题已经成为历史了。直通线:两端均使用568A或者568B的线序,用于不同类的网络设备互联,如电脑和交换机,交换机和路由器等交叉线:一端使用568A先序,一端568B线序,用于同类设备的连接,如交换机与交换机,电脑和电脑等不过现在的网络设备都支持自动适配接口类型功能,所以不管是直通线还是交叉线,都可以正常使用。568A和568B标准: 568A标准:白绿,绿,白橙,蓝,白…

    2022年6月19日
    32
  • 《n8n基础教学》第一节:如何使用编辑器UI界面

    《n8n基础教学》第一节:如何使用编辑器UI界面

    2026年3月15日
    3

发表回复

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

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