1. 程式人生 > 其它 >c++ shared_ptr 和 左右值 關係記錄

c++ shared_ptr 和 左右值 關係記錄

#include <iostream>
#include <deque>
using namespace std;


template<class T>
class my_shared_ptr
{
private:
    T* m_ptr = nullptr;
    unsigned int* m_ref_count = nullptr;
public:
    my_shared_ptr():m_ptr(nullptr),m_ref_count(nullptr){}
    my_shared_ptr(T* ptr):m_ptr(ptr),m_ref_count(new
unsigned int(1)){} //複製語義 my_shared_ptr(const my_shared_ptr& obj) { m_ptr = obj.m_ptr; m_ref_count = obj.m_ref_count; if (m_ref_count != nullptr) { (*m_ref_count)++; } } my_shared_ptr& operator=(const my_shared_ptr& obj) {
delete m_ptr; m_ptr = obj.m_ptr; delete m_ref_count; m_ref_count = obj.m_ref_count; if (m_ref_count != nullptr) { (*m_ref_count)++; } return *this; } //移動語義 my_shared_ptr(my_shared_ptr&& dying_obj) :m_ptr(nullptr), m_ref_count(nullptr) {//
my_shared_ptr<A> move_ctor_ptr(std::move(a_ptr)); dying_obj.swap(*this); } my_shared_ptr& operator=(my_shared_ptr&& dying_obj) {//move_assign_ptr = std::move(b_ptr); my_shared_ptr(std::move(dying_obj)).swap(*this); return *this; } void swap(my_shared_ptr& other) { std::swap(m_ptr, other.m_ptr); std::swap(m_ref_count, other.m_ref_count); } unsigned int use_count() const { return m_ref_count == nullptr? 0:*m_ref_count; } //解構函式 ~my_shared_ptr() { if (m_ref_count == nullptr) return; (*m_ref_count)--; if (*m_ref_count > 0) return; //如果引用計數到了0,則刪除指標 if (m_ptr != nullptr) delete m_ptr; delete m_ref_count; } }; struct A { std::string m_str; A(std::string s) :m_str(s) { cout << "construct" << endl; } ~A() { cout << "destruct" << endl; } }; int main() { my_shared_ptr<A> empty_ptr; cout << "empty:" << empty_ptr.use_count() << endl; my_shared_ptr<A> a_ptr(new A("a")); cout << "a:" << a_ptr.use_count() << endl; my_shared_ptr<A> copied_ptr(a_ptr); cout << "copy:" << copied_ptr.use_count() << endl; cout << "a:" << a_ptr.use_count() << endl; my_shared_ptr<A> move_ptr(std::move(a_ptr)); cout << "move:" << move_ptr.use_count() << endl; cout << "a:" << a_ptr.use_count() << endl; return 0; }

————————————

左值複製

void set(const string & var1, const string & var2){
  m_var1 = var1;  //copy
  m_var2 = var2;  //copy
}
A a1;
string var1("string1");
string var2("string2");
a1.set(var1, var2); // OK to copy

————————————

右值(臨時變數)移動

void set(string && var1, string && var2){
  //avoid unnecessary copy!
  m_var1 = std::move(var1);  
  m_var2 = std::move(var2);
}
A a1;
//temporary, move! no copy!
a1.set("temporary str1","temporary str2");

——————————————

std::forword 兩者集大成,用模板,當左值時複製,右值時移動

template<typename T1, typename T2>
void set(T1 && var1, T2 && var2){
  m_var1 = std::forward<T1>(var1);
  m_var2 = std::forward<T2>(var2);
}

//when var1 is an rvalue, std::forward<T1> equals to static_cast<[const] T1 &&>(var1)
//when var1 is an lvalue, std::forward<T1> equals to static_cast<[const] T1 &>(var1)