C++简单实现shared_ptr的代码

实现一个简单的shared_ptr需要考虑以下几个方面:

1.计数器实现:将指针的计数器放在一个自定义类中,当有多个shared_ptr指向同一个对象时,计数器加1;当一个指针被销毁时,计数器减1;当计数器为0时,释放对象所占用的内存。

2.拷贝构造函数和赋值运算符实现:在拷贝构造函数和赋值运算符中,需要将新对象的计数器指向原对象的计数器,使得两个对象指向同一个计数器。同时,需要保证原计数器的值加1,新计数器的值等于原计数器的值。

以下是实现shared_ptr的示例代码:

template<typename T>
class shared_ptr {
public:
  // 构造函数
  shared_ptr(T* ptr = nullptr) {
    if (ptr) {
      data = new Counter(ptr);
    }
  }

  // 拷贝构造函数
  shared_ptr(const shared_ptr<T>& ptr) {
    data = ptr.data;
    if (data) {
      data->counter++;
    }
  }

  // 赋值运算符
  shared_ptr<T>& operator=(const shared_ptr<T>& ptr) {
    if (this != &ptr) {
      release();
      data = ptr.data;
      if (data) {
        data->counter++;
      }
    }
    return *this;
  }

  // 重载*运算符
  T& operator*() const {
    return *(data->ptr);
  }

  // 重载->运算符
  T* operator->() const {
    return data->ptr;
  }

  // 获取计数器
  int use_count() const {
    if (data) {
      return data->counter;
    } else {
      return 0;
    }
  }

  // 释放指针,如果计数器为0,则删除对象
  void release() {
    if (data) {
      data->counter--;
      if (data->counter == 0) {
        delete data;
      }
    }
    data = nullptr;
  }

  // 析构函数
  ~shared_ptr() {
    release();
  }
private:
  struct Counter {
    Counter(T* p = nullptr) : ptr(p), counter(1) {}
    ~Counter() { delete ptr; }
    T* ptr;
    int counter;
  };
  Counter* data;
};

示例1:使用shared_ptr共享指针

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

class MyClass {
public:
    MyClass() { std::cout << "MyClass()" << std::endl; }
    ~MyClass() { std::cout << "~MyClass()" << std::endl; }
};

int main() {
    shared_ptr<MyClass> p1(new MyClass); // 创建p1
    shared_ptr<MyClass> p2(p1); // 复制构造函数,p1、p2计数器都为2
    std::cout << "p1 use_count: " << p1.use_count() << std::endl; 
    std::cout << "p2 use_count: " << p2.use_count() << std::endl; 
    shared_ptr<MyClass> p3 = p1; // 赋值运算符,p1、p2、p3计数器都为3
    std::cout << "p1 use_count: " << p1.use_count() << std::endl; 
    std::cout << "p2 use_count: " << p2.use_count() << std::endl; 
    std::cout << "p3 use_count: " << p3.use_count() << std::endl; 
    return 0; // 离开作用域,p1、p2、p3计数器都为0,MyClass会被自动释放
}

输出:

MyClass()
p1 use_count: 2
p2 use_count: 2
p1 use_count: 3
p2 use_count: 3
p3 use_count: 3
~MyClass()

示例2:shared_ptr数组

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

class MyClass {
public:
    MyClass(int n) : data(new int[n]) { std::cout << "MyClass()" << std::endl; }
    ~MyClass() { delete[] data; std::cout << "~MyClass()" << std::endl; }
    int* data;
};

int main() {
    shared_ptr<MyClass[]> p1(new MyClass[3](5)); // 创建包含3个MyClass对象的数组
    std::cout << "p1[1].data[2]: " << p1[1].data[2] << std::endl; // 访问数组
    return 0; // 离开作用域,MyClass数组会被自动释放
}

输出:

MyClass()
MyClass()
MyClass()
p1[1].data[2]: 5
~MyClass()
~MyClass()
~MyClass()

这里需要注意的是,shared_ptr的数组版本需要将单个类型的模板参数改为数组类型的模板参数,然后通过重载下标运算符来访问数组元素。同时,数组需要使用new[]开辟空间,使用delete[]释放空间。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++简单实现shared_ptr的代码 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • 浅谈JSON.parse()和JSON.stringify()

    浅谈JSON.parse()和JSON.stringify() JSON.parse()和JSON.stringify()是JavaScript中常用的JSON数据解析和生成方法,它们可以让我们轻松地将JavaScript的对象或数组转换为JSON格式,或者将JSON格式的数据转换为JavaScript的对象或数组。本文将从以下几个方面进行详细讲解: JSO…

    C 2023年5月23日
    00
  • C/C++ Qt 运用JSON解析库的实例代码

    下面将为您详细讲解在C/C++ Qt中运用JSON解析库的实例代码的完整攻略。 一、JSON简介 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。JSON建立在两种结构上:一个用来表示值的简单原始类型(数字、字符串、布尔值、空值)以及一种集合值的有序列表(数组)和一个包含…

    C 2023年5月23日
    00
  • json格式解析和libjson的用法介绍(关于cjson的使用方法)

    一、JSON格式解析简介 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。与XML类似,JSON也是一种无须定义复杂DTD(Data Type Definition,数据类型定义),就可直接使用的格式。由于其简明的格式、易于阅读等特性,得到了广泛的应用。 二、libjson的用法介绍 简介 libjson是一个C…

    C 2023年5月23日
    00
  • 浅谈文章排名 百度是如何给网页排序的

    下面就来详细讲解“浅谈文章排名 百度是如何给网页排序的”的完整攻略,包含以下几个方面: 前言 搜索引擎是我们日常生活中必不可少的一环,百度是国内最大的搜索引擎之一。在百度搜索结果页面中,排名靠前的网页往往会获得更多的流量和点击量,这对于网站的SEO来说非常重要。那么,百度是如何给网页排序的呢? 百度排序算法 百度的排序算法主要是基于网页的关键词匹配程度和网页…

    C 2023年5月22日
    00
  • C语言实现客房管理系统

    C语言实现客房管理系统的完整攻略包含以下几个步骤: 设计数据结构和功能模块 首先需要设计客房管理系统的数据结构和功能模块。根据系统需要,可以设计出以下数据结构: Room:客房信息,包括客房号、类型、价格、当前状态(已入住或未入住)等。 Order:订单信息,包括客房号、入住时间、退房时间、客人姓名等。 根据这些数据结构,可以设计出以下功能模块: Check…

    C 2023年5月23日
    00
  • C程序读取键盘码的方法

    C程序要想读取键盘码有以下几种方法: 使用getc()函数读取单个字符 可以使用stdlib.h库中的getc()函数来读取单个字符。 int getc(FILE *stream); 这个函数可以从指定的流中读取下一个字符,可以从键盘输入流stdin中读取字符。 示例1:下面这个程序可以读取用户从键盘输入的字符,并将其输出到屏幕上。 #include &lt…

    C 2023年5月23日
    00
  • 用c语言实现和平精英的完整代码

    如果要用C语言实现和平精英的完整代码,需要进行以下步骤: 1. 确认游戏功能 首先,需要确认和平精英的游戏功能,例如枪械、人物、地图等。这是实现代码的基础。 2. 学习游戏引擎 要实现和平精英游戏代码,需要学习相应游戏引擎,例如Unity或Unreal Engine。根据游戏引擎的特性和C语言的语法,实现游戏代码。 3. 设计游戏逻辑 实现游戏代码前,需要设…

    C 2023年5月23日
    00
  • C/C++实现矩阵的转置(示例代码)

    C/C++实现矩阵的转置(示例代码) 矩阵的转置指的是将矩阵的行和列互换的一个操作。在编程中,实现矩阵的转置可以用来优化矩阵变换的计算,也可以用来解决图像处理、信号处理等问题。下面我们将介绍如何使用C/C++来实现矩阵的转置。 一、矩阵转置的实现方法 方法一:使用二维数组 在C/C++中,使用二维数组可以很方便地表示矩阵。我们可以通过遍历矩阵元素的方式,将矩…

    C 2023年5月24日
    00
合作推广
合作推广
分享本页
返回顶部