2023年7月5日
手写独立指针
/// author: Tang Guofang/// date: 2023-07-05/// description:/// 手写独立指针,主要包含删除器和指针两个成员变量。/// 其他的就是常规的构造函数、拷贝构造函数与赋值函数,析构函数,重载*和->操作符。#include <iostream>
/// @brief 删除器/// @tparam T 模板类型template <typename T>class DefaultDeleter {public: /// @brief 仿函数,功能为重置形参目标 /// @param ptr 传入的指针,也是被删除的指针 void operator()(T* ptr) { if (ptr) { delete ptr; ptr = nullptr; } }};
/// @brief 手写独立指针/// @tparam T 模板类型/// @tparam Deleter 删除器,默认为DefaultDeletertemplate <typename T, typename Deleter = DefaultDeleter<T>>class unique_ptr {private: /// @brief 实际指针 T* ptr_; /// @brief 删除器的实例 Deleter del_;
public: /// @brief 构造函数 /// @param ptr 传入的指针,默认为空指针 explicit unique_ptr(T* ptr = nullptr) : ptr_(ptr) {} /// @brief 拷贝构造函数,禁止拷贝构造 /// @param p 传入的指针 unique_ptr(const unique_ptr& p) = delete; /// @brief 赋值函数,禁止赋值 /// @param p 传入的指针 /// @return unique_ptr& unique_ptr& operator=(const unique_ptr& p) = delete; unique_ptr(unique_ptr&& p) : ptr_(p.ptr_) { p.ptr_ = nullptr; } unique_ptr& operator=(unique_ptr&& p) { std::swap(this->ptr_, p.ptr_); p.ptr_ = nullptr; } /// @brief 常规的*和->操作符 /// @return T& T* 引用与指针 T& operator*() { return *ptr_; } T* operator->() { return ptr_; } /// @brief 布尔返回,判断指针是否为空 operator bool() const { return ptr_ != nullptr; } /// @brief 常规的get函数 /// @return T* 指针 T* get() const { return ptr_; } /// @brief 释放指针,并返回实际指针 /// @return T* 实际指针 T* release() { T* pointer = ptr_; ptr_ = nullptr; return pointer; } /// @brief 重置指针 /// @param ptr 传入的指针 void reset(T* ptr) { unique_ptr<T, Deleter>().swap(*this); ptr_ = ptr; } /// @brief 交换指针 /// @param p 传入的指针 void swap(unique_ptr& p) { std::swap(ptr_, p.ptr_); }
#if use_deleter /// @brief 析构函数,调用删除器 ~unique_ptr() { del_(ptr_); }#else /// @brief 析构函数,不调用删除器 ~unique_ptr() { if (ptr_ != nullptr) { delete ptr_; ptr_ = nullptr; } }#endif};
int main() { unique_ptr<int> unq_ptr(new int(10)); unique_ptr<int> unq_ptr2 = std::move(unq_ptr); printf("unq_ptr2: %d\n", *unq_ptr2); unique_ptr<int> unq_ptr3(std::move(unq_ptr2)); printf("unq_ptr3: %d\n", *unq_ptr3); std::cout << unq_ptr.get() << std::endl; std::cout << unq_ptr2.get() << std::endl; std::cout << unq_ptr3.get() << std::endl; if (unq_ptr) { printf("unq_ptr: %d\n", *unq_ptr); } else { printf("unq_ptr is nullptr\n"); }}