#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)