当前位置: 首页 > news >正文

指针指针的实现

上一篇文章简单介绍了一下智能指针,这次我们简单讲解一下实现和具体的例子,及分析。

1. Unique_Ptr 实现

unique_ptr 是一种独占所有权的智能指针,不允许拷贝,只允许移动。它确保资源只被一个所有者拥有,并在所有者被销毁时自动释放资源。

实现:


// 默认删除器
struct DefaultDeleter {
    template <typename T>
    void operator()(T* ptr) const {
        delete ptr;
    }
};

// UniquePtr 类模板
template <typename T, typename Deleter = DefaultDeleter>
class UniquePtr {
private:
    T* ptr;

public:
    // 默认构造函数,初始化为 nullptr
    constexpr UniquePtr()noexcept 
     : ptr(nullptr) 
    {}

    // 从指针构造
    explicit constexpr UniquePtr(T* p) noexcept 
      : ptr(p) 
    {}

    // 禁止拷贝构造
    UniquePtr(const UniquePtr& other) = delete;

    // 禁止拷贝赋值
    UniquePtr& operator=(const UniquePtr& other) = delete;

    // 移动构造函数
    constexpr UniquePtr(UniquePtr&& other) noexcept 
        : ptr(other.ptr) {
        other.ptr = nullptr;
    }

    // 移动赋值运算符
    UniquePtr& operator=(UniquePtr&& other) noexcept {
        if (this != &other) {
            reset(other.ptr);
            other.ptr = nullptr;
        }
        return *this;
    }

    // 析构函数,释放资源
    ~UniquePtr() {
        reset();
    }

    // 重置指针
    void reset(T* p = nullptr) {
        if (ptr != p) {
            Deleter()(ptr);
            ptr = p;
        }
    }

    // 释放所有权
    T* release() noexcept {
        T* ret = ptr;
        ptr = nullptr;
        return ret;
    }

    // 获取指针
    T* get() const noexcept {
        return ptr;
    }

    // 重载解引用运算符
    T& operator*() const {
        return *ptr;
    }

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

    // 转换为 bool
    explicit operator bool() const noexcept {
        return ptr != nullptr;
    }

    // 禁止隐式转换为其他指针类型
    template <typename U>
    operator U*() const = delete;
};

使用例子:

int main() {
    UniquePtr<int> up1(new int(42));
    cout << "*up1 = " << *up1 << endl;

    UniquePtr<int> up2 = move(up1);
    if (!up1) {
        cout << "up1 is empty after move." <<endl;
    }

    cout << "*up2 = " << *up2 << endl;

    up2.reset();
    if (!up2) {
        cout << "up2 is empty after reset." << endl;
    }

    return 0;
}
//输出
*up1 = 42
up1 is empty after move.
*up2 = 42
up2 is empty after reset.

 

2. Shared_Ptr 实现

shared_ptr 是一种共享所有权的智能指针,使用引用计数来管理对象的生命周期。多个 shared_ptr 可以共享同一个对象,当最后一个 shared_ptr 被销毁时,资源被释放。

 


template <typename T>
class SharedPtr {
private:
    T* ptr;             // 原始指针
    size_t* count;      // 引用计数

public:
    // 构造函数
    explicit SharedPtr(T* p = nullptr) 
     : ptr(p)
      , count(new size_t(1)) {
        if (p == nullptr) {
            *count = 0;
        }
    }

    // 拷贝构造函数
    SharedPtr(const SharedPtr<T>& other)
     : ptr(other.ptr)
     , count(other.count) {
        if (ptr) {
            (*count)++;
        }
    }

    // 析构函数
    ~SharedPtr() {
        release();
    }

    // 拷贝赋值运算符
    SharedPtr<T>& operator=(const SharedPtr<T>& other) {
        if (this != &other) {
            release();
            ptr = other.ptr;
            count = other.count;
            if (ptr) {
                (*count)++;
            }
        }
        return *this;
    }

    // 解引用运算符
    T& operator*() const {
        return *ptr;
    }

    // 箭头运算符
    T* operator->() const {
        return ptr;
    }

    // 获取引用计数
    size_t use_count() const {
        return *count;
    }

    // 获取原始指针
    T* get() const {
        return ptr;
    }

    // 重置指针
    void reset(T* p = nullptr) {
        release();
        ptr = p;
        count = new size_t(1);
        if (p == nullptr) {
            *count = 0;
        }
    }

private:
    // 释放资源
    void release() {
        if (ptr && --(*count) == 0) {
            delete ptr;
            delete count;
            ptr = nullptr;
            count = nullptr;
        }
    }
};

举例:

class MyClass {
public:
    MyClass()
 { 
        cout << "MyClass constructed\n";
 }
    ~MyClass()
 {
         cout << "MyClass destroyed\n";
 }
    void print() 
{
         cout << "Hello from MyClass\n"; 
}
};

int main() {
    // 创建shared_ptr
    SharedPtr<MyClass> ptr1(new MyClass());
    cout << "Use count: " << ptr1.use_count() << endl;  //输出1
    
    {
        // 拷贝构造
        SharedPtr<MyClass> ptr2 = ptr1;
        cout << "Use count: " << ptr1.use_count() << endl;  // 输出2
        ptr2->print();
    }
    
    cout << "Use count: " << ptr1.use_count() << endl;  // 输出1
    
    // 赋值操作
    SharedPtr<MyClass> ptr3;
    ptr3 = ptr1;
    cout << "Use count: " << ptr1.use_count() << endl;  //输出 2
    
    // 重置指针
    ptr1.reset(new MyClass());
    cout << "Use count: " << ptr1.use_count() << endl;  //输出 1
    
    return 0;
}

3. Weak_Ptr 实现

weak_ptr 是一种不拥有所有权的智能指针,用于配合 shared_ptr 使用,以解决循环引用问题。weak_ptr 不影响引用计数,但可以通过 lock() 方法获取一个 shared_ptr,以访问对象。

实现代码:

template <typename T>
class WeakPtr {
private:
    T* ptr;             // 指向被管理的对象
    size_t* shared_count;  // 指向 shared_ptr 的引用计数
    size_t* weak_count;    // 指向 weak_ptr 的引用计数

public:
    // 默认构造函数
    WeakPtr() 
    : ptr(nullptr)
    , shared_count(nullptr)
    , weak_count(nullptr) 
    {}

    // 从 shared_ptr 构造
    WeakPtr(const SharedPtr<T>& shared) 
        : ptr(shared.get())
        ,shared_count(shared.get_count_ptr())
        ,weak_count(new size_t(1)) {
        if (shared_count) {
            (*weak_count)++;
        }
    }

    // 拷贝构造函数
    WeakPtr(const WeakPtr<T>& other)
        : ptr(other.ptr)
        , shared_count(other.shared_count)
        ,weak_count(other.weak_count) {
        if (weak_count) {
            (*weak_count)++;
        }
    }

    // 析构函数
    ~WeakPtr() {
        release();
    }

    // 拷贝赋值运算符
    WeakPtr<T>& operator=(const WeakPtr<T>& other) {
        if (this != &other) {
            release();
            ptr = other.ptr;
            shared_count = other.shared_count;
            weak_count = other.weak_count;
            if (weak_count) {
                (*weak_count)++;
            }
        }
        return *this;
    }

    // 从 shared_ptr 赋值
    WeakPtr<T>& operator=(const SharedPtr<T>& shared) {
        release();
        ptr = shared.get();
        shared_count = shared.get_count_ptr();
        weak_count = new size_t(1);
        if (shared_count) {
            (*weak_count)++;
        }
        return *this;
    }

    // 尝试提升为 shared_ptr
    SharedPtr<T> lock() const {
        if (expired()) {
            return SharedPtr<T>();
        }
        return SharedPtr<T>(*this);
    }

    // 检查是否过期
    bool expired() const {
        return shared_count == nullptr || *shared_count == 0;
    }

    // 获取引用计数信息
    size_t use_count() const {
        return shared_count ? *shared_count : 0;
    }

private:
    // 释放资源
    void release() {
        if (weak_count && --(*weak_count) == 0) {
            if (shared_count && *shared_count == 0) {
                delete ptr;
                delete shared_count;
            }
            delete weak_count;
        }
    }
};

这里我们得修改shared_ptr用来支持weak_ptr

修改:

template <typename T>
class SharedPtr {
    // ... (之前的实现保持不变)
    
    // 新增方法,供 WeakPtr 访问
    size_t* get_count_ptr() const { return count; }
    
    // 新增构造函数,供 WeakPtr::lock() 使用
    SharedPtr(const WeakPtr<T>& weak) 
        : ptr(weak.ptr)
        , count(weak.shared_count) {
        if (count && *count > 0) {
            (*count)++;
        } else {
            ptr = nullptr;
            count = nullptr;
        }
    }
};

使用例子:

int main() {
    // 创建 shared_ptr
    SharedPtr<MyClass> shared(new MyClass());
    
    // 创建 weak_ptr
    WeakPtr<MyClass> weak = shared;
    
    // 使用 weak_ptr
    if (auto locked = weak.lock()) {
        locked->print();  // 安全使用
        :cout << "Use count: " << locked.use_count() << endl;
    }
    
    // 释放 shared_ptr
    shared.reset();
    
    // 检查 weak_ptr 是否过期
    if (weak.expired()) {
        cout << "Object has been deleted" << endl;
    }
    
    return 0;
}

实现就结束了,基本定义参考我上篇文章,如有错误还请评论区纠正。 

 

 

 

 

 

 

相关文章:

  • 01分数规划
  • bash脚本手动清空mysql表数据
  • Java——抽象方法抽象类 接口 详解及综合案例
  • 从零到一:基于DeepSeek-R1的智能贪吃蛇开发实战
  • 【JAVA】常用的JDK8、JDK17 以及 JDK21 的主要新特性和演进过程
  • Ubuntu22安装docker28
  • .DS_Store文件泄露、.git目录泄露、.svn目录泄露漏洞利用工具
  • 驱动-字符设备驱动框架
  • Java学习手册:JVM、JRE和JDK的关系
  • 宇视设备视频平台EasyCVR打造智慧酒店安防体系,筑牢安全防线
  • openEuler Mugen 测试框架
  • 从PDF中提取表格:以GB/T2260—2007为例
  • js实现生肖宜忌展示
  • Linux重启命令(Linux Restart Command)
  • JS包装类型Array
  • 发票查验与OCR识别:财务流程的智慧双保险
  • java+postgresql+swagger-单表批量和循环insert、delete操作(八)
  • 人工智能:GPT技术应用与未来展望
  • c++进阶之----c++11(包装器)
  • Elasticsearch 官网阅读学习笔记01