智能指针简单实现

如何实现一个简单的智能指针 所谓智能指针指的是一种用起来像指针但又无需关心内存管理的一种机制。   普通指针的问题 C/C++中指针极为常见,但普通指针最大的问题就在于需要程序员记住分配内存后要手动释放,否则就会有内存泄漏或者引用野指针的风险。 比如有这样一个简单的类: class person { public: person() {} ~person(){ cout<<"delete... 阅读详情

//SmartPointer,h

#ifndef _SMARTPOINTER_H_
#define _SMARTPOINTER_H_

namespace practice
{

template <typename T>
class pointer
{
 protected:
    T *m_ptr;
public:
      explicit pointer(T *ptr = nullptr) noexcept : m_ptr(ptr)
      {
      }
      pointer(const pointer<T>& obj) noexcept : m_ptr(obj.m_ptr)
      {
      }
      operator bool () const
      {
          return nullptr != m_ptr;
      }
      bool operator ! () const
      {
          return nullptr == m_ptr;
      }
      T& operator *()
      {
          return *m_ptr;
      }
      T *operator -> ()
      {
          return m_ptr;
      }
      T& operator *() const
      {
          return *m_ptr;
      }
      T *operator -> () const
      {
          return m_ptr;
      }
      T *get()
      {
          return m_ptr;
      }
      bool is_null() const
      {
          return nullptr == m_ptr;
      }
      virtual ~pointer() noexcept
      {
      }
};


template <typename T>
class unique_ptr : public pointer<T>
{
protected:
    void set_null(const unique_ptr<T>& obj)
    {
        const_cast< unique_ptr<T>& >(obj).m_ptr = nullptr;
    }
public:
    explicit unique_ptr(T *ptr = nullptr ) noexcept : pointer<T>(ptr)
    {
    }
    unique_ptr(const unique_ptr<T>& obj) noexcept :  pointer<T>(obj)
    {
         set_null(obj);
    }
    unique_ptr<T>& operator = (const unique_ptr<T>& obj)
    {
        if( this != &obj )
        {
            reset(obj.m_ptr);
            set_null(obj);
        }
        return *this;
    }
    T *take()
    {
        T *tmp = this->m_ptr;
        this->m_ptr = nullptr;
        return tmp;
    }
    void swap(unique_ptr<T>& obj)
    {
        T *tmp = obj.m_ptr;
        obj.m_ptr = this->m_ptr;
        this->m_ptr = tmp;
    }
    void reset(T *ptr = nullptr)
    {
        delete this->m_ptr;
        this->m_ptr = ptr;
    }
    ~unique_ptr() noexcept
    {
        reset(nullptr);
    }
};


template <typename T>
class shared_ptr : public pointer<T>
{
protected:
    unsigned *m_count;

    void increase_count(const shared_ptr<T>& obj)
    {
        if( nullptr != obj.m_count )
        {
          ++(*const_cast<shared_ptr<T>& >(obj).m_count);
        }
        this->m_count = obj.m_count;
    }
    void decrease_count()
    {
        if( (nullptr != this->m_count) && (0 == --(*this->m_count)) )
        {
            delete this->m_ptr;
            delete this->m_count;
        }
    }
public:
    explicit shared_ptr( T *ptr = nullptr) noexcept : pointer<T>(ptr)
    {
        if( nullptr != ptr )
        {
            this->m_count = new unsigned(1);
        }
        else
        {
            this->m_count = nullptr;
        }
    }
    shared_ptr(const shared_ptr<T>& obj) noexcept : pointer<T>(obj)
    {
        increase_count(obj);
    }
    shared_ptr<T>& operator = (const shared_ptr<T>& obj)
    {
        if( this != &obj )
        {
            decrease_count();
            increase_count(obj);

            this->m_ptr = obj.m_ptr;
        }
        return *this;
    }
    bool unique()
    {
        return 1 == *this->m_count;
    }
    unsigned use_count()
    {
        return *this->m_count;
    }
    ~shared_ptr() noexcept
    {
        decrease_count();
    }
};


}

#endif // _SMARTPOINTER_H_



//main.cpp

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

using namespace std;

class test
{
 public:
    void print()
    {
        cout << "test" << endl;
    }
};

void test_unique()
{
    practice::unique_ptr<int> p(new int(10));
    if( p )
    {
        cout << "if( p )" << endl;
    }

    practice::unique_ptr<int> p2(p);
    if( !p )
    {
        cout << "if( !p )" << endl;
    }

    p = p2;
    if( p2.is_null() )
    {
        cout << "p2.is_null()" << endl;
    }

    p2.swap(p);
    if( nullptr != p2.get() )
    {
        cout << "nullptr != p2.get()" << endl;
    }

    cout << "*p2 = " << *p2 << endl;

    int *t = p2.take();
    cout << "*t = " << *t << endl;
    delete t;

    p2.reset(new int(0));

    cout << "*p2 = " << *p2 << endl;

    practice::unique_ptr<test> pt(new test);
    pt->print();
}

void test_share()
{
    practice::shared_ptr<int> p(new int(100));
    if( p )
    {
        cout << "if( p )" << endl;
    }
    if( false == !p )
    {
        cout << "false == !p" << endl;
    }

    practice::shared_ptr<int> p2(p);
    if( 2 == p.use_count() )
    {
        cout << "2 == p.use_count()" << endl;
    }
    p = p2;

    practice::shared_ptr<int> p3(new int(1));
    p2 = p3;
    if( p.unique() )
    {
        cout << "p.unique()" << endl;
    }

    *p = 10;
    cout << "*p = " << *p << endl;

    cout <<"* p3.get() = " << * p3.get() << endl;

     practice::shared_ptr<test> p4(new test);
     p4->print();
}

int main()
{
    test_unique();
    test_share();
    
    return 0;
}



//本来想加上删除器的,无奈,模板暂时没有好的方法使模板实参个数与构造函数实参个数一致,按照对标准库中的智能指针的测试来看,拿std::uniq_ptr来说:

std::uniq_ptr的两个模板参数,第一个为内部管理的指针指向的对象类型,第二个参数为删除器类型,虽然说第二个模板参数可以是默认删除器,但只要为模板类提供了删除器类型,就必须使用两个实参去调用构造函数,使用一个实参调用构造函数编译器报错,同样的,如果使用默认模板删除器,必须使用一个实参去调用构造函数,使用两个实参编译器报错。如 std::uniq_ptr<int, void(*)(int *)> p(&a)与std::uniq_ptr<int> p2(&a, fun)编译器应该报错,因为模板实参个数与构造函数实参个数不一致,std::uniq_ptr<int, void(*)(int *)> p(&a, func)与std::uniq_ptr<int> p2(&a)编译器不会报错,但是我目前不能做到这一点。


删除器是一个可调用对象,其参数为智能指针内部封装的原生指针,使用默认删除器的情况下,智能指着的析构函数被调用时,删除器其会对原生指针进行释放操作,delete (p),如果传入了自定义的删除器,将会是deleter(p)


参考:C++ Primer 第五版 
智能指针之unique_ptr简单实现-实现篇 1 序 1.1 智能指针 为了避免手动在堆中分配出的内存没有释放造成内存泄露的问题,C++11提供了智能指针。 智能指针将指针封装成一个栈对象。栈对象在生命周期结束自动销毁时会调用析构函数。智能指针基本上也是在析构函数中做文章,实现的堆上内存管理。 C++11推荐使用的智能指针有unique_ptr、shared_ptr和weak_ptr三种。 1.2 内容简介 本文为std::unique_ptr的实现篇,介绍实现一个UniquePtr类,实现与std::unique_ptr类似的功能。代码实现参考了st 阅读详情

相关推荐

C++智能指针及其简单实现

C++智能指针及其简单实现

jacke121的专栏 2580

C++新特性17_智能指针的原理(智能指针引子;指出什么是智能指针;为使利用类构造析构管理资源释放更像指针,对运算符进行重载,但会因重复析构造成崩溃,提出禁止和拷贝移动方法,均有缺陷;推荐新指针方法)

1. 什么是只能指针? (1)用起来像指针 (2) 会自己对资源进行释放 2. 手动进行资源的释放形式 在没有智能指针之前,我们都是采用手动释放的方法。 #include <iostream> #include <vector> #include <algorithm> #include <functional> using namespace std; //智能指针 //1.用起来像指针 //2.会自己对资源进行释放 class CStudent {

分享学习成长历程,Winter is coming! 2086

从‘数字分身’到‘数字员工’:华为云MetaStudio如何重塑企业生产力?

本文探讨了华为云MetaStudio如何通过数字人技术重塑企业生产力,从数字分身到数字员工的转变。通过多模态AIGC技术,MetaStudio在金融、零售和制造业等多个行业实现高效应用,显著提升服务质量和运营效率。数字员工不仅降低成本,更成为企业增长的新引擎。

weixin_29083475的博客 450

智能指针的简单实现

智能指针就是利用系统调用函数执行完后自动释放栈实现的,从而规避程序员忘记释放内存的风险。。。。简单的智能指针实现如下 // smart_ptr.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include &lt;iostream&gt; using namespace std; template&lt;class T&gt; class smar...

Mr Lin 的专栏 410

ABB机器人发送实时位置给PLC

本文使用中断方式实现,多任务要订购ABB功能包 Profinet总线组变量配置 注:映射为16位和32位均可用 声明数据 VAR num CurrentExAxisPos;!外轴位置 VAR robtarget pCurrentPos;!实时位置 var intnum TrapNum;!中断号 初始化开中断 IDelete TrapNum;!中断号 CONNECT TrapNum WITH iTrapCurPos;!连接中...

澍澍爸的blog 6777

Pinocchio 结合 CasADi 进行 IK 逆运动学及 Mujoco 仿真

摘要:本视频演示了如何利用Pinocchio和CasADi实现机械臂逆运动学(IK)求解,并在Mujoco中进行仿真。通过构建优化问题(最小化位姿误差),结合IPOPT求解器对机械臂关节角度进行优化。代码支持导入URDF/MJCF模型,并以so100机械臂为例,实现了末端执行器位置跟踪的仿真测试。关键步骤包括:建立平移/旋转误差函数、设置约束条件、调用CasADi求解,最终在Mujoco中实时更新关节状态完成运动控制。

darcsdn 1002

智能指针的简单实现(unique_ptr和shared_ptr)

给出了C++的unique_ptr和shared_ptr的简单实现的源代码,并配有详细注释帮助理解。

T_killer_的博客 428

Halcon和C#联合编程实现硬币识别(个人入门练习)

本人为机器视觉入门小白,自己突发奇想 1.图片数据来源和分析 2.HALCON实现 3.C#搭建界面框架 4.C#中嵌入HALCON代码,即联合编程 5.导出.exe文件,运行以及Debug 目标是这样的,在图片中识别出每种类型的硬币数量,然后计算出总钱数。先上结果,再细说过程。 C#界面和识别结果: 1.图片数据来源和分析 图片大小及格式均统一,拍摄的时候已经尽可能的去除了背景噪点,所以图像处理的要求并不很高(重点在于思路)。硬币区分原理本人代码采用直径范围来判断(也可以半径或区域面积,HALCON算子

Demobird的博客 3616

C++智能指针及简单实现

根据智能指针的功能实现一个简单的智能指针类,并探讨智能指针的一些问题和思路

Law of Conservation of Eudaemonia 572

保姆级教程:用YOLOv5s搞定钢材表面缺陷检测,从数据集NEU-DET到模型部署全流程

本文提供了一份详细的YOLOv5s钢材表面缺陷检测教程,涵盖从NEU-DET数据集处理到模型部署的全流程。针对工业环境中的实际限制,如计算资源有限和标注样本少等问题,提供了优化方案和实用技巧,帮助开发者快速实现高效的钢材缺陷检测系统。

weixin_30568591的博客 465

PCB作为智能小车底盘的设计方法与工程实践

PCB底盘是一种将机械结构与电子设计深度融合的嵌入式系统集成方案,其本质是利用印制电路板的高精度制造能力(±0.05mm孔位公差)和FR-4材料的结构强度(弯曲强度345MPa),替代传统亚克力或铝合金底盘。该方案通过封装库驱动的正向设计、机械层语义化定义及机电协同布局,实现安装基准统一、共地平面优化与RF天线集成等技术价值。广泛应用于教育机器人、AGV小车、模块化开发平台等对空间紧凑性、量产一致性与电磁兼容性有严苛要求的移动嵌入式场景,尤其适合具备EDA工具使用能力的电子工程师主导的跨学科开发流程。

weixin_36064575的博客 129

C++ 手动实现简单的智能指针类

何为智能指针,即不需要用户再自动手动New和Delete掉,由内部类进行new和delete,这样可以防止用户忘记释放掉指针而造成的内存泄漏。 这里简单的实现unique_ptr智能指针的方式。 头文件 // 自制智能指针类头文件 template<typename T> class SmartPointer{ public: SmartPointer(T* ptr_); ~S...

MusicMan 1617

华为OD机考双机位C卷 - 区间交集(Java & Python& JS & C/C++ & GO )

华为OD机考双机位C卷 - 区间交集

算法大师! 1136

智能指针的简单实现及两种误用方式

最近在自己写智能指针的时候,遇到了一些小的疑惑,也纠正了之前的一些理解上的偏差。 首先是最简单的智能指针的一个实现: template class SmartPointer{ private: T* ptr; public: SmartPointer(T* p) :ptr(p){} //构造函数 T& operator*(){ //重载*操作符

a3137732的博客 1521

UltraScale系列底层结构(3)——URAM概述

在UltraScale+™ 器件中,除了我们在常规熟悉的BRAM资源以外,还额外提供了URAM(UltraRAM)资源。 UltraRAM 是一种单时钟同步操作的高密度存储器,每个 UltraRAM 块可存储 288 Kb 数据,配置为 4K x 72 位的存储单元,其容量是 Block RAM 的八倍。虽然 UltraRAM 内部使用单端口存储单元,但通过在一个时钟周期内顺序执行端口 A 和端口 B 的操作,实现了双端口功能。

apple_53311083的博客 2833

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

用c++简单实现智能指针

用c++简单实现智能指针       什么是智能指针?答案相当简单;智能指针是聪明的普通指针。这是什么意思?实际上,智能指针是一些对象,表现出普通指针的功能但是比普通指针多做了一些事情。这些对象像普通指针一样灵活,并且管理对象有自己的优点(比如构造器和自动析构)。智能指针解决了普通指针的一些问题。       普通指针的问题。       我们使用C++语言中的指针,最常见的问题是什么?内存

xinpo66的专栏 1978

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

关于智能指针的简单实现

但是如果new的时候给类对象赋值就不会有这情况,这就能运行通过,也能删除,不知道因为啥?其实关于指针是大的烦恼就是忘记删除New出来的内存,关于这点现在推出智能指针,其实说白了就是把指针封装成一个类的对象,让类对像自动析构的时候删除指针。如果用前面的方法就是用完后删除了,p1的指针也就没有了,肯定要出问题的。这个时候p2只是要用一个p1中的指针来获取数据,并不想删除其指针,但是如果是外部的智能指针对象呢,你不可能删除别人的管理的指针吧。2.那么问题来了,这是管理外部的指针是没有问题的,

qq_31178679的博客 130

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

基于C++实现一个简单的智能指针类

在C、C++类的语言当中对指针的使用是十分常见和重要的,但是使用指针也很容易导致内存泄漏、不安全的情况发生,本文就针对这种情况来实现一个简单的智能指针类,通过这个类实现对指针操作的封装,降低使用指针带来的负面影响。 一、实现智能指针的两个类 1、RefBase类 这个类的具体实现如下: /* 定义一个引用计数的基类 */ class RefBase{ private: int cnt;

TECH_PRO的博客 1417

shared_ptr智能指针的简单实现

#ifndef SHARED_PTR_H #define SHARED_PTR_H #include <stdio.h> #include <iostream> using namespace std; template <typename T> // 泛型编程 class Shared_ptr { public: Shared_ptr() : m_p...

MaxMaxXiong的博客 234

一个智能指针的简单实现

智能指针初探

ypy9323的博客 434

自己实现简单的智能指针

#include #include using namespace std; template class share { public: share():point(0){} share(T* p1) { point = p1; } ~share() { cout << "begin to delete share" << endl; if

chenycbbc0101的博客 2504

C++ 智能指针简单实现

C++标准库中定义智能指针shared_ptr< T >类型,内部使用了引用计数的方式执行内存的垃圾回收。本文实现一个简单的智能指针,探究内部实现方式。 #include <iostream> using namespace std;template <typename T> class SmartPtr;template <typename T> class U_Ptr // 辅助类 { pri

每天进步一点点 423
上一篇: C++重载箭头操作符的理解
下一篇: 父类中访问子类成员
早起的虫儿灬
博客等级 码龄10年 54粉丝 114原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值