c++ 实现智能指针shared_ptr

2023-11-05

sharedPtr.h

#ifndef _sharedPtr_H__
#define _sharedPtr_H__

class sharedPtr {
public:
	sharedPtr();
	sharedPtr(int*);
	sharedPtr(const sharedPtr&);
	sharedPtr(sharedPtr&&);
	
	sharedPtr& operator=(const sharedPtr&);
	sharedPtr& operator=(sharedPtr&&);

	int& operator*();
	int useCount();

	~sharedPtr();
private:
	int* ptr;
	int* use_count;  // 引用计数
};

#endif

sharedPtr.cpp

#include "sharedPtr.h"
#include <iostream>

sharedPtr::sharedPtr() :ptr(nullptr), use_count(new int(0)) {
}

sharedPtr::sharedPtr(int* p){
	if (p == nullptr) {
		ptr = nullptr;
		use_count = new int(0);
	}
	else {
		ptr = p;
		use_count = new int(1);
	}
}

// 拷贝构造函数
sharedPtr::sharedPtr(const sharedPtr& p) {
	// 如果空指针的话 引用计数等于0
	this->ptr = p.ptr;
	this->use_count = p.use_count;
	if(p.ptr != nullptr){
		(*use_count)++;
	}
}

// 移动构造函数 移交控制权
sharedPtr::sharedPtr(sharedPtr&& p) {
	this->ptr = p.ptr;
	this->use_count = p.use_count;
	p.ptr = nullptr;
	p.use_count = nullptr;

}

sharedPtr& sharedPtr::operator=(const sharedPtr& p) {
	ptr = p.ptr;
	use_count = p.use_count;
	(*use_count)++;
	return *this;
}

sharedPtr& sharedPtr::operator=(sharedPtr&& p) {
	this->ptr = p.ptr;
	this->use_count = p.use_count;
	p.ptr = nullptr;
	p.use_count = nullptr;
	return *this;
}

int& sharedPtr::operator* () {
	return *ptr;
}

sharedPtr::~sharedPtr() {
	if (this->use_count == nullptr) {
		delete ptr;
		delete use_count;
		std::cout << "释放内存空间" << std::endl;
	}
	else {
		(*use_count)--;
		if (*(this->use_count) == 0) {
			delete ptr;
			delete use_count;
			std::cout << "释放内存空间" << std::endl;
		}
	}

}

int sharedPtr::useCount() {
	if (use_count == nullptr) {
		return 0;
	}
	return *use_count;
}

test.cpp

#include <iostream>
#include <memory>
#include "sharedPtr.h"
using namespace std;

int main()
{
    sharedPtr ptr(nullptr);
    cout << ptr.useCount() << endl;
    sharedPtr ptr1(new int(10));
    cout << *ptr1 << endl;
    cout << ptr1.useCount() << endl;

    {
        sharedPtr ptr2(ptr1);
        cout << ptr1.useCount() << endl;
    }

    sharedPtr ptr3 = ptr1;
    cout << ptr1.useCount() << endl;
    sharedPtr ptr4 = move(ptr3);
    cout << ptr1.useCount() << endl;
    cout << ptr3.useCount() << endl;
    cout << ptr4.useCount() << endl;

    //shared_ptr<int> ptr(nullptr);
    //cout << ptr.use_count() << endl;
    //shared_ptr<int> ptr1(new int(10));
    //cout << *ptr1 << endl;
    //cout << ptr1.use_count() << endl;
    //shared_ptr<int> ptr2(ptr1);
    //cout << ptr1.use_count() << endl;
    //shared_ptr<int> ptr3 = ptr2;
    //cout << ptr1.use_count() << endl;
    //shared_ptr<int> ptr4 = move(ptr3);
    //cout << ptr1.use_count() << endl;
    //cout << ptr3.use_count() << endl;
    //cout << ptr4.use_count() << endl;

    return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++ 实现智能指针shared_ptr 的相关文章

  • C# 静态类型不能用作参数

    public static void SendEmail String from String To String Subject String HTML String AttachmentPath null String Attachme
  • 与 for_each 或 std::transform 一起使用时,如何调用 C++ 函子构造函数

    我以前从未使用过 C 函子 所以我只是想了解它们是如何工作的 例如假设我们有这个函子类 class MultiplyBy private int factor public MultiplyBy int x factor x int ope
  • 在 C 语言中,为什么数组的地址等于它的值?

    在下面的代码中 指针值和指针地址与预期不同 但数组值和地址则不然 怎么会这样 Output my array 0022FF00 my array 0022FF00 pointer to array 0022FF00 pointer to a
  • strlen() 编译时优化

    前几天我发现你可以找到编译时strlen使用这样的东西 template
  • Boost ASIO 串行写入十六进制值

    我正在使用 ubuntu 通过串行端口与设备进行通信 所有消息都必须是十六进制值 我已经在 Windows 环境中使用白蚁测试了通信设置 并得到了我期望的响应 但在使用 Boost asio 时我无法得到任何响应 以下是我设置串口的方法 b
  • 在 Mono 中反序列化 JSON 数据

    使用 Monodroid 时 是否有一种简单的方法可以将简单的 JSON 字符串反序列化为 NET 对象 System Json 只提供序列化 不提供反序列化 我尝试过的各种第三方库都会导致 Mono Monodroid 出现问题 谢谢 f
  • 如何在 C# 中将 Json 转换为对象

    我想将 Json 转换为 C 中的对象 这里的 Json 是 值 e920ce0f e3f5 4c6f 8e3d d2fbc51990e4 如何使用 Object 问题看似愚蠢 但其实并不那么愚蠢 我没有简单的 Json 我有 IEnume
  • Android NDK 代码中的 SIGILL

    我在市场上有一个 NDK 应用程序 并获得了有关以下内容的本机崩溃报告 SIGILL信号 我使用 Google Breakpad 生成本机崩溃报告 以下是详细信息 我的应用程序是为armeabi v7a with霓虹灯支持 它在 NVIDI
  • JavaScript 错误:MVC2 视图中的条件编译已关闭

    我试图在 MVC2 视图页面中单击时调用 JavaScript 函数 a href Select a JavaScript 函数 function SelectBenefit id code alert id alert code 这里 b
  • OpenGL:如何检查用户是否支持glGenBuffers()?

    我检查了文档 它说 OpenGL 版本必须至少为 1 5 才能制作glGenBuffers 工作 用户使用的是1 5版本但是函数调用会导致崩溃 这是文档中的错误 还是用户的驱动程序问题 我正在用这个glGenBuffers 对于VBO 我如
  • Unity手游触摸动作不扎实

    我的代码中有一种 错误 我只是找不到它发生的原因以及如何修复它 我是统一的初学者 甚至是统一的手机游戏的初学者 我使用触摸让玩家从一侧移动到另一侧 但问题是我希望玩家在手指从一侧滑动到另一侧时能够平滑移动 但我的代码还会将玩家移动到您点击的
  • SQLAPI++ 的免费替代品? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有任何免费 也许是开源 的替代品SQLAPI http www sqlapi com 这个库看起来
  • 当Model和ViewModel一模一样的时候怎么办?

    我想知道什么是最佳实践 我被告知要始终创建 ViewModel 并且永远不要使用核心模型类将数据传递到视图 这就说得通了 让我把事情分开 但什么是Model 和ViewModel一模一样 我应该重新创建另一个类还是只是使用它 我觉得我应该重
  • 读取依赖步行者输出

    I am having some problems using one of the Dlls in my application and I ran dependency walker on it i am not sure how to
  • 以编程方式创建 Blob 存储容器

    我有一个要求 即在创建公司时 在我的 storageaccount 中创建关联的 blob 存储容器 并将容器名称设置为传入的字符串变量 我已尝试以下操作 public void AddCompanyStorage string subDo
  • 使用 gcc 时在头文件中查找定义的好方法是什么?

    在使用 gcc 时 有人有推荐的方法在头文件中查找定义吗 使用 MSVC 时 我只需右键单击并选择 转到定义 这非常好 我使用过 netbeans gcc 它确实有代码帮助 包括到定义的超链接 所以这是一种选择 但是 我想知道是否有任何其他
  • 构建 C# MVC 5 站点时项目之间的处理器架构不匹配

    我收到的错误如下 2017 年 4 月 20 日构建 13 23 38 C Windows Microsoft NET Framework v4 0 30319 Microsoft Common targets 1605 5 警告 MSB3
  • 任何人都可以清楚地告诉如何在不使用像 这样的预定义函数的情况下找到带有小数值或小数值的指数吗? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 例如 2 0 5 1 414 所以想要 我是 c 的新手 所以请解释简单的逻辑 如果不是复杂的逻辑也足够了 在数学中 从整数取幂到实数
  • 如何在 C# 中获取 CMD/控制台编码

    我需要指定正确的代码页来使用 zip 库打包文件 正如我所见 我需要指定控制台编码 在我的例子中为 866 C Users User gt mode Status for device CON Lines 300 Columns 130 K
  • 如何为有时异步的操作创建和实现接口

    假设我有数百个类 它们使用 计算 方法实现公共接口 一些类将执行异步 例如读取文件 而实现相同接口的其他类将执行同步代码 例如将两个数字相加 为了维护和性能 对此进行编码的好方法是什么 到目前为止我读到的帖子总是建议将异步 等待方法冒泡给调

随机推荐