心血来潮,自实现标准库的shared_ptr

2023-11-14

#include <iostream>
#include <memory>
#include <map>

using namespace std;

template<typename T>
class myShared_ptr{
public:
    myShared_ptr(T* ptr = nullptr){
        _ptr = ptr;
        if(nullptr != ptr){
            _ptrMap.insert(std::make_pair<T* &, int>(ptr, 1)); 
                               // std::make_pairs<T* &,int>(), 注意这种用法,建议用{ptr, 1}
        }
    }
    
    myShared_ptr(const myShared_ptr & another){
        if( nullptr != another._ptr){
            _ptr = another._ptr;
            _ptrMap[_ptr]++;
        }
    }

    myShared_ptr& operator=(const myShared_ptr& another){
        if (this != &another) {
            if (--_ptrMap[_ptr] <= 0 && nullptr != _ptr) {
                delete _ptr;
                _ptr = nullptr;
                _ptrMap.erase(_ptr);
            }
            _ptr = another._ptr;
            _ptrMap[another._ptr]++;
        }
        return *this;
    }

    ~myShared_ptr(){
        if (--_ptrMap[_ptr] <= 0 && nullptr != _ptr) {
            delete _ptr;
            _ptr = nullptr;
            _ptrMap.erase(_ptr);
        }
    }

    int use_count(){
        return _ptrMap[_ptr];
    }
    
    T operator*(){
        return *_ptr;
    }
    
    T *operator->(){
        return _ptr;
    }
private:
    T * _ptr;
    static map<T*,int> _ptrMap;
};

template<typename T>
map<T*,int> myShared_ptr<T>::_ptrMap;


#if 0 //实现标准库的shared_ptr的功能
class Base{
public:
    Base(Base*ptr){*this = *ptr;} //为了匹配第84行的代码
    Base(){cout << "Base()" << endl;}
    ~Base(){cout << "~Base()" << endl;}
};

void func(){
    myShared_ptr<Base> p1(new Base);//
    myShared_ptr<Base> p2(p1);
    
    cout << "p1: " << p1.use_count() << endl;
    cout << "p2: " << p2.use_count() << endl;
    
    //~ p2 = std::make_shared<Base>(new Base); //得自实现make_shared<>
                                               //因为make_shared<> 返回的是 shared_ptr<>
    myShared_ptr<Base> p3 = new Base;
    p2 = p3;
    
    cout << "p1: " << p1.use_count() << endl;
    cout << "p2: " << p2.use_count() << endl;
    cout << "p3: " << p3.use_count() << endl;
    
    p2 = nullptr;
    
    cout << "p1: " << p1.use_count() << endl;
    cout << "p2: " << p2.use_count() << endl;
    cout << "p3: " << p3.use_count() << endl;
    
}
#endif

#if 1  //循环引用的毛病, 待myWeak_ptr解决
class Son;
class Father{
public:
    Father(){cout << "Father()" << endl;}
    ~Father(){cout << "~Father()" << endl;}
    myShared_ptr<Son> _ptrSon;
};

class Son{
public:
    Son(){cout << "Son()" << endl;}
    ~Son(){cout << "~Son()" << endl;}
    myShared_ptr<Father> _ptrFat;
};

void func(){
    myShared_ptr<Father> pF = new Father;
    myShared_ptr<Son> pS = new Son;
    
    //~ pF->_ptrSon = pS;
    //~ pS->_ptrFat = pF;
}
#endif


int main(){
    func();
    return 0;
}

 

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

心血来潮,自实现标准库的shared_ptr 的相关文章

  • 检查两个数是否是彼此的排列?

    给定两个数字 a b 使得 1 例如 123 是 312 的有效排列 我也不想对数字中的数字进行排序 如果您指的是数字的字符 例如 1927 和 9721 则 至少 有几种方法 如果允许排序 一种方法是简单地sprintf将它们放入两个缓冲
  • 如何检查图像对象与资源中的图像对象是否相同?

    所以我试图创建一个简单的程序 只需在单击图片框中更改图片即可 我目前只使用两张图片 所以我的图片框单击事件函数的代码 看起来像这样 private void pictureBox1 Click object sender EventArgs
  • 无法使用已与其底层 RCW 分离的 COM 对象。在 oledb 中

    我收到此错误 但我不知道我做错了什么 下面的代码在backrgroundworker中 将异常详细信息复制到剪贴板 System Runtime InteropServices InvalidComObjectException 未处理 通
  • 访问私人成员[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 通过将类的私有成员转换为 void 指针 然后转换为结构来访问类的私有成员是否合适 我认为我无权修改包含我需要访问的数据成员的类 如果不道德 我
  • 获取按下的按钮的返回值

    我有一个在特定事件中弹出的表单 它从数组中提取按钮并将标签值设置为特定值 因此 如果您要按下或单击此按钮 该函数应返回标签值 我怎样才能做到这一点 我如何知道点击了哪个按钮 此时代码返回 DialogResult 但我想从函数返回 Tag
  • 将数组向左或向右旋转一定数量的位置,复杂度为 o(n)

    我想编写一个程序 根据用户的输入 正 gt 负 include
  • Newtonsoft JSON PreserveReferences处理自定义等于用法

    我目前在使用 Newtonsoft Json 时遇到一些问题 我想要的很简单 将要序列化的对象与所有属性和子属性进行比较以确保相等 我现在尝试创建自己的 EqualityComparer 但它仅与父对象的属性进行比较 另外 我尝试编写自己的
  • 指针问题(仅在发布版本中)

    不确定如何描述这一点 但我在这里 由于某种原因 当尝试创建我的游戏的发布版本进行测试时 它的敌人创建方面不起作用 Enemies e level1 3 e level1 0 Enemies sdlLib 500 2 3 128 250 32
  • C 预处理器库

    我的任务是开发源分析工具C程序 并且我需要在分析本身之前预处理代码 我想知道什么是最好的图书馆 我需要一些重量轻 便于携带的东西 与其推出自己的 为什么不使用cpp这是的一部分gcc suite http gcc gnu org onlin
  • 指针减法混乱

    当我们从另一个指针中减去一个指针时 差值不等于它们相距多少字节 而是等于它们相距多少个整数 如果指向整数 为什么这样 这个想法是你指向内存块 06 07 08 09 10 11 mem 18 24 17 53 7 14 data 如果你有i
  • Discord.net 无法在 Linux 上运行

    我正在尝试让在 Linux VPS 上运行的 Discord net 中编码的不和谐机器人 我通过单声道运行 但我不断收到此错误 Unhandled Exception System Exception Connection lost at
  • 插入记录后如何从SQL Server获取Identity值

    我在数据库中添加一条记录identity价值 我想在插入后获取身份值 我不想通过存储过程来做到这一点 这是我的代码 SQLString INSERT INTO myTable SQLString Cal1 Cal2 Cal3 Cal4 SQ
  • C++ fmt 库,仅使用格式说明符格式化单个参数

    使用 C fmt 库 并给定一个裸格式说明符 有没有办法使用它来格式化单个参数 example std string str magic format 2f 1 23 current method template
  • 需要哪个版本的 Visual C++ 运行时库?

    microsoft 的最新 vcredist 2010 版 是否包含以前的版本 2008 SP1 和 2005 SP1 还是我需要安装全部 3 个版本 谢谢 你需要所有这些
  • 控制到达非 void 函数末尾 -wreturn-type

    这是查找四个数字中的最大值的代码 include
  • 将文本叠加在图像背景上并转换为 PDF

    使用 NET 我想以编程方式创建一个 PDF 它仅包含一个背景图像 其上有两个具有不同字体和位置的标签 我已阅读过有关现有 PDF 库的信息 但不知道 如果适用 哪一个对于如此简单的任务来说最简单 有人愿意指导我吗 P D 我不想使用生成的
  • 在 Dynamics CRM 插件中访问电子邮件发件人地址

    我正在编写一个 Dynamics CRM 2011 插件 该插件挂钩到电子邮件实体的更新后事件 阶段 40 pipeline http msdn microsoft com en us library gg327941 aspx 并且在此阶
  • 32 位到 64 位内联汇编移植

    我有一段 C 代码 在 GNU Linux 环境下用 g 编译 它加载一个函数指针 它如何执行并不重要 使用一些内联汇编将一些参数推送到堆栈上 然后调用该函数 代码如下 unsigned long stack 1 23 33 43 save
  • 为什么 C# Math.Ceiling 向下舍入?

    我今天过得很艰难 但有些事情不太对劲 在我的 C 代码中 我有这样的内容 Math Ceiling decimal this TotalRecordCount this PageSize Where int TotalRecordCount
  • 为什么我收到“找不到编译动态表达式所需的一种或多种类型。”?

    我有一个已更新的项目 NET 3 5 MVC v2 到 NET 4 0 MVC v3 当我尝试使用或设置时编译出现错误 ViewBag Title财产 找不到编译动态表达式所需的一种或多种类型 您是否缺少对 Microsoft CSharp

随机推荐