Skip to main content

Cpp和UE智能指针详解

· 4 min read

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

只支持移动构造和移动赋值

//
// 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;


}