Cpp和UE智能指针详解
shared_ptr
Section titled “shared_ptr”//// Created by 王晨辉 on 2023/8/7.//
#include <iostream>
#define LINE std::cout << "\n*************************************\n" << std::endl;#define BLOCK(x) std::cout << "\n\n\n********** " <<#x << " ********* \n\n\n";#define Print(x) std::cout << #x << " cnt : " << x.use_count() << " value: "<< *x << std::endl;
namespace MySharedPtr { template<typename T> class shared_ptr { public: // ctor explicit shared_ptr(T* objPtr);
// dtor ~shared_ptr();
// copy ctor shared_ptr(const shared_ptr& other);
// copy assignment shared_ptr& operator=(const shared_ptr& other);
// dereference T operator*(){return *m_data;};
// count int use_count(){return *m_cnt;};
// get T* get(){return m_data;};
private: T *m_data; int *m_cnt; };
template<typename T, typename... Args> shared_ptr<T> make_shared(Args&&... args){ return shared_ptr<T>(new T(std::forward<Args>(args)...)); }}
int main() { {// std using std::shared_ptr; using std::make_shared;
shared_ptr<int> a(new int(10)); Print(a) // 1 10
// int raw = 1; // 不要把栈里变量的地址给shared_ptr int* raw = new int(1); shared_ptr<int> b(raw); Print(b) // 1 1
auto c = make_shared<int>(10); Print(c) // 1 10
auto d = make_shared<int>(*raw); Print(d) // 1 1
// copy construct / copy assignment auto e = d; // 浅拷贝 Print(e) // 2 1 shared_ptr<int> g(e); // 浅拷贝 Print(g) // 3 1 auto f = make_shared<int>(*d); // 深拷贝 Print(f) // 1 1
// dereference auto pa = a.get(); std::cout << *pa << std::endl; // 10 *pa = 2; std::cout << *a << std::endl; // 2 }
LINE;
{// MySharedPtr using MySharedPtr::shared_ptr; using MySharedPtr::make_shared;
shared_ptr<int> a(new int(10)); Print(a) // 1 10
// int raw = 1; // 不要把栈里变量的地址给shared_ptr int* raw = new int(1); shared_ptr<int> b(raw); Print(b) // 1 1
auto c = make_shared<int>(10); Print(c) // 1 10
auto d = make_shared<int>(*raw); Print(d) // 1 1
// copy construct / copy assignment auto e = d; // 浅拷贝 Print(e) // 2 1 shared_ptr<int> g(e); // 浅拷贝 Print(g) // 3 1 auto f = make_shared<int>(*d); // 深拷贝 Print(f) // 1 1
// dereference auto pa = a.get(); std::cout << *pa << std::endl; // 10 *pa = 2; std::cout << *a << std::endl; // 2 }
}
template<typename T>MySharedPtr::shared_ptr<T>::shared_ptr(T* obj):m_data(obj), m_cnt(new int(1)){}
template<typename T>MySharedPtr::shared_ptr<T>::~shared_ptr(){ (*m_cnt)--; if(*m_cnt == 0){ delete m_data; delete m_cnt; }}
template<typename T>MySharedPtr::shared_ptr<T>::shared_ptr(const shared_ptr<T> &other) { m_data = other.m_data; m_cnt = other.m_cnt; (*m_cnt)++;}
template<typename T>MySharedPtr::shared_ptr<T>& MySharedPtr::shared_ptr<T>::operator=(const MySharedPtr::shared_ptr<T>& other) { if(this == &other) return *this; (*m_cnt)--; if(*m_cnt == 0){ delete m_cnt; delete m_data; } m_data = other.m_data; m_cnt = other.cnt; *(m_cnt)++;}unique_ptr
Section titled “unique_ptr”只支持移动构造和移动赋值
//// Created by 王晨辉 on 2023/8/11.////// Created by 王晨辉 on 2023/8/7.//
#include <iostream>#include <memory>
#define LINE std::cout << "\n*************************************\n" << std::endl;#define BLOCK(x) std::cout << "\n\n\n********** " <<#x << " ********* \n\n\n";
namespace MyUniquePtr{ template<typename T> class unique_ptr{ private: T* m_data;
public: unique_ptr(T* p = nullptr):m_data(p){} unique_ptr(const unique_ptr<T>&) = delete; unique_ptr& operator=(const unique_ptr<T>&) = delete; unique_ptr(unique_ptr<T>&& other):m_data(other){ other.ptr = nullptr; } unique_ptr& operator=(unique_ptr<T>&& other) noexcept { if(this == &other){ return *this; } delete m_data; m_data = other.m_data; other.m_data = nullptr; return *this; } ~unique_ptr(){delete m_data;} T* get() const {return m_data;} };}
std::unique_ptr<int> pass_through(std::unique_ptr<int> p){ return p;}
int main() { {// std using std::shared_ptr; using std::unique_ptr; using std::make_shared; using std::make_unique;
unique_ptr<int> p = std::make_unique<int>(1);// unique_ptr<int> q = pass_through(p); // error unique_ptr has no copy ctor unique_ptr<int> q1 = std::move(p); // it has only move ctor// unique_ptr<int> q2(std::move(p)); // move ctor but error for p has pass the ownership to q1 unique_ptr<int> q3(std::move(q1)); std::cout << *q3 << std::endl;
unique_ptr<int> w = std::make_unique<int>(1); q3 = std::move(w); // move assignment std::cout << *q3 << std::endl;
}
LINE;
}