首页 > 编程语言 >C++的四种智能指针及简单实现

C++的四种智能指针及简单实现

时间:2024-05-20 16:57:13浏览次数:26  
标签:count C++ 运算符 shared unique my ptr 四种 指针

C++的四种智能指针及简单实现

参考:C++智能指针讲解及模拟实现

一、auto_ptr

  • auto_ptr有拷贝语义,拷贝后源对象变为空指针,可能引发严重问题
template<class T>
class my_unique_ptr{
private:
    T *_ptr;
public:
    // 普通构造函数
    my_unique_ptr(T *ptr) : _ptr(ptr){}
    // 拷贝构造函数
    my_unique_ptr(my_unique_ptr<T> a_ptr){
        _ptr = a_ptr._ptr;
        a_ptr._ptr = nullptr;
    }

    // 析构函数
    ~my_unique_ptr(){
        if(_ptr){
            delete _ptr;
            _ptr = nullptr;
        }
    }

    // 重载*运算符
    T& operator*(){
        return *_ptr;
    }

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

    // 重载=运算符
    my_unique_ptr<T>& operator=(my_unique_ptr<T> a_ptr){
        if(this != &a_ptr){
            delete _ptr;
            _ptr = a_ptr._ptr;
            a_ptr.ptr = nullptr;
        }
        return *this;
    }
};

二、unique_ptr

  • 与auto_ptr类似,但是没有拷贝语义,但是允许使用移动语义
template<class T>
class my_unique_ptr{
private:
    T *_ptr;
public:
    // 普通构造函数
    my_unique_ptr(T *ptr) : _ptr(ptr){}
    // 拷贝构造函数
    my_unique_ptr(my_unique_ptr<T> a_ptr)=delete;

    // 析构函数
    ~my_unique_ptr(){
        if(_ptr){
            delete _ptr;
            _ptr = nullptr;
        }
    }

    // 重载*运算符
    T& operator*(){
        return *_ptr;
    }

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

    // 重载=运算符
    my_unique_ptr<T>& operator=(my_unique_ptr<T> a_ptr)=delete;
public:
    const T* get(){
        return _ptr;
    }

    size_t use_count(){
        return *_count;
    }
};

三、shared_ptr

  • 多个shared_ptr可以指向同一处资源,当所有shared_ptr被只放时,该处资源才被释放
template<class T>
class my_shared_ptr{
private:
    T *_ptr;
    int *_count;

public:
    // 普通构造函数
    my_shared_ptr(T *ptr) : _ptr(ptr), _count(new int(1)){}
    // 拷贝构造函数
    my_shared_ptr(my_shared_ptr<T> &s_ptr){
        _ptr = s_ptr._ptr;
        _count = s_ptr._count;
        ++(*_count);
    }
    // 析构函数
    ~my_shared_ptr(){
        --(*_count);
        if(0 == (*_count)){
            if(_ptr){
                delete _ptr;
            }
            delete _count;
        }
    }

    // 重载*运算符
    T& operator*(){
        return *_ptr;
    }

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

    // 重载=运算符
    my_shared_ptr<T>& operator=(my_shared_ptr<T> u_ptr){
        // 避免自己给自己赋值
        if(_ptr != u_ptr._ptr){
            // 减少原先指向对象的引用
            --(*_count);
            if(0 == (*_count)){
                if(_ptr){
                    delete _ptr;
                }
                delete _count;
            }
            // 拷贝
            _ptr = u_ptr._ptr;
            _count = u_ptr._count;
            ++(*count);
        }
    }
};

四、weak_ptr

  • weak_ptr是一种弱引用型指针,不控制所指向对象生存期的智能指针,主要为了解决循环引用问题和悬空指针问题
template<class T>
class my_weak_ptr
{
private:
    T *_ptr;
    size_t _shared_count;
public:
    my_weak_ptr(const my_shared_ptr<T> &s_ptr) _ptr(s_ptr._ptr), _shared_count(s_ptr._count);
    my_weak_ptr(const my_weak_ptr<T> &w_ptr) _ptr(w_ptr._ptr), _shared_count(s_ptr._shared_count);

    // 重载*运算符
	T& operator*()
	{
		return *_ptr;
	}

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

    // 重载=运算符
    my_weak_ptr<T>& operator=(const my_shared_ptr<T>& s_ptr)
	{
		_ptr = s_ptr.get();
		return *this;
	}
};

标签:count,C++,运算符,shared,unique,my,ptr,四种,指针
From: https://www.cnblogs.com/yujunjiang/p/18202204

相关文章

  • 关于一重指针和二重指针的区别和联系
    一、关键词指针,二重指针二:知识点1.指针的本身地址、指针所指向地址、指针所指向地址内容本身地址:指针也是一个类型,通常是在64位系统上是8字节,32位是4字节。既然是类型对象就需要存储地址,因此本身地址指的是用于存储指针这个变量值的地址。指针指向地址:指针是个变量,这个变......
  • 指针练习班级成绩
    1.求第一门课程的平均分2.找出有两门以上不及格的学生3.找出平均分在90分以上或全部课程在85分以上的学生#include<stdio.h>#include<math.h>#include<string.h>#defineM4#defineN5voidAverage(int*arr,intn);voidTwoFail(int*arr);voidOutputFail(int(*p)[N......
  • C++算法刷题基础
    1.main函数的返回类型一定是int2.C++语言为我们准备了一组内置库,包含了很多常用的功能,并且这些内置库可以直接使用,而其中的内置库:iostream,就提供了输入和输出的功能,允许开发者从键盘读取输入并在屏幕上输出结果。3.在iostream库中,我们有两个对象可以使用,分别是cin和cout。......
  • 侯捷C++上期笔记
    1.头文件和类、构造函数c++和c最大的不同在于C++会把数据以及处理数据的函数放到一个对象objects(class)里,不同类之间不可见,类似C中结构体struct防止头文件重复声明ifndefcomplex//当之前没有声明过这个头文件时,才进行后续的声明definecomplex(2)补充定义(1)类定义(3)类功能解释......
  • C++身份证二要素实名认证api、实名认证接口
    在数字化时代背景下,个人信息安全成为了社会关注的焦点。为进一步加强网络空间的安全管理,提升服务效率,身份证实名认证接口的出现为各行业提供了更为安全、高效的身份验证解决方案。随着互联网+政务服务、金融科技、电子商务等领域的快速发展,实名认证需求日益增长。翔云身......
  • 指针数组练习排列字符串
    用指针数组实现排列字符串#include<stdio.h>#include<math.h>#include<string.h>#defineN5voidOrderString(char*p[],intn);intmain(){char*arr[10]={"Hello","Howareyou?","I'mfine","Ilovecomputer......
  • C++ 异常处理注意事项总结
    C++异常处理注意事项总结:异常安全代码:编写异常安全的代码是至关重要的。这意味着你的代码应该在面对异常时能够正确地清理资源并维持程序状态。使用RAII(ResourceAcquisitionIsInitialization)技术可以帮助自动管理资源,减少内存泄漏的风险。使用noexcept:对于不会抛出异常......
  • C++ 多线程编程要点总结
    C++多线程编程要点总结:选择合适的线程库:C++11引入了 <thread> 头文件,提供了对线程的原生支持。也可以使用第三方库,如Boost.Thread,它提供了更多高级功能和更好的跨平台兼容性。线程创建与管理:使用 std::thread 类创建新线程,并传入函数或可调用对象作为线程的入口......
  • 线程安全使用 HashMap 的四种技巧
    这篇文章,我们聊聊线程安全使用HashMap的四种技巧。1方法内部:每个线程使用单独的HashMap如下图,tomcat接收到到请求后,依次调用控制器Controller、服务层Service、数据库访问层的相关方法。每次访问服务层方法serviceMethod时,都会在方法体内部创建一个单独的HashMap,......
  • C++中 符号的优先级
    符号运算顺序::从左至右a++a--type()type{}a()a[].->从左至右!~++a--a+a-a(type)sizeof&a*anewnew[]deletedelete[]从右至左.*->*从左至右a*ba/ba%b从左至右a+ba-b从左至右<<>>从左至右<<=>>=从左至右==!......