欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

tinystl实现(第十九步:memory.h实现)

程序员文章站 2022-05-24 19:06:20
...

经过长时间的学习终于可以开始tinystl的仿(chao)写工作了,本文参考了这位大神的github,坦白讲我只是补充了注释,因为tinystl的代码真的非常经典而我又没什么这种大型项目的经验,所以只能这样做,不过相信能够有助于大家的学习
#强烈建议按顺序阅读本专栏
memory.h实际上定义了两种智能指针,share_ptr和unique_ptr,两者都是非常重要的指针,阅读这篇博客了解他们

#pragma once
#ifndef _MEMORY_H_
#define _MEMORY_H_

#include <utility>

#include "Detail\Ref.h"

namespace mySTL {
	template<class _T>
	class cow_ptr;

	//利用default_delete进行delete
	template<class T>
	struct default_delete {
		void operator ()(T* ptr) { if (ptr) delete ptr; }
	};
	template<class T>
	struct default_delete < T[] > {
		void operator ()(T* ptr) { if (ptr) delete[] ptr; }
	};

	template<class T, class D = default_delete<T>>
	class unique_ptr {//智能指针uniqueptr
	public:
		typedef T element_type;
		typedef D deleter_type;
		typedef element_type *pointer;
	public:
		explicit unique_ptr(T *data = nullptr) :data_(data) {}
		unique_ptr(T *data, deleter_type del) :data_(data), deleter(del) {}

		unique_ptr(unique_ptr&& up) :data_(nullptr) {
			mySTL::swap(data_, up.data_);
		}
		unique_ptr& operator = (unique_ptr&& up) {
			if (&up != this) {
				clean();
				mySTL::swap(*this, up);
			}
			return *this;
		}
		//禁用对常引用的复制
		unique_ptr(const unique_ptr&) = delete;
		unique_ptr& operator = (const unique_ptr&) = delete;

		~unique_ptr() { clean(); }
		//返回值
		const pointer get()const { return data_; }
		pointer get() { return data_; }
		//返回指定的析构器
		deleter_type& get_deleter() { return deleter; }
		const deleter_type& get_deleter()const { return deleter; }
		//检查是否为空
		operator bool()const { return get() != nullptr; }
		//将当前数据返回并把当前指针置为空
		pointer release() {
			T *p = nullptr;
			mySTL::swap(p, data_);
			return p;
		}
		//
		void reset(pointer p = pointer()) {
			clean();
			data_ = p;
		}
		//大同小异的基本操作
		void swap(unique_ptr& up) { mySTL::swap(data_, up.data_); }

		const element_type& operator *()const { return *data_; }
		const pointer operator ->()const { return data_; }
		element_type& operator *() { return *data_; }
		pointer operator ->() { return data_; }
	private:
		//先调用deleter再置空
		inline void clean() {
			deleter(data_);
			data_ = nullptr;
		}
	private:
		element_type *data_;
		deleter_type deleter;
	};
	template <class T, class D>
	void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) {
		x.swap(y);
	}
	//大同小异的基本操作
	template <class T1, class D1, class T2, class D2>
	bool operator == (const unique_ptr<T1, D1>& lhs, const unique_ptr<T2, D2>& rhs) {
		return lhs.get() == rhs.get();
	}
	template <class T, class D>
	bool operator == (const unique_ptr<T, D>& up, nullptr_t p) {
		return up.get() == p;
	}
	template <class T, class D>
	bool operator == (nullptr_t p, const unique_ptr<T, D>& up) {
		return up.get() == p;
	}
	template <class T1, class D1, class T2, class D2>
	bool operator != (const unique_ptr<T1, D1>& lhs, const unique_ptr<T2, D2>& rhs) {
		return !(lhs == rhs);
	}
	template <class T, class D>
	bool operator != (const unique_ptr<T, D>& up, nullptr_t p) {
		return up.get() != p;
	}
	template <class T, class D>
	bool operator != (nullptr_t p, const unique_ptr<T, D>& up) {
		return up.get() != p;
	}
	//
	template <class T, class... Args>
	unique_ptr<T> make_unique(Args&&... args) {
		return unique_ptr<T>(new T(std::forward<Args>(args)...));
	};
	//智能指针shared_ptr
	template<class T>
	class shared_ptr {
	public:
		typedef T element_type;
	private:
		template<class Type>
		using ref_t = Detail::ref_t < Type >;//本质上是ref
	public:
		explicit shared_ptr(T *p = nullptr) :ref_(new ref_t<T>(p)) {}
		template<class D>
		shared_ptr(T *p, D del) : ref_(new ref_t<T>(p, del)) {}

		shared_ptr(const shared_ptr& sp) {
			copy_ref(sp.ref_);
		}

		shared_ptr& operator = (const shared_ptr& sp) {
			if (this != &sp) {
				decrease_ref();
				copy_ref(sp.ref_);
			}
			return *this;
		}

		~shared_ptr() { decrease_ref(); }
		//大同小异的基本操作
		const element_type& operator *()const { return *(get()); }
		const element_type *operator ->()const { return get(); }
		element_type& operator *() { return *(get()); }
		element_type *operator ->() { return get(); }

		const element_type* get() const { return ref_->get_data(); }
		element_type* get() { return ref_->get_data(); }
		size_t use_count() const { return ref_->count(); }

		operator bool() const { return get() != nullptr; }
	private:
		void decrease_ref() {
			if (ref_->get_data()) {
				--(*ref_);
				if (use_count() == 0)
					delete ref_;
			}
		}
		void copy_ref(ref_t<T> *r) {//正确的拷贝ref_t
			ref_ = r;
			++(*ref_);
		}
	private:
		ref_t<T> *ref_;

	public:
		template<class _T>
		friend class cow_ptr;
	};
	//大同小异的基本操作
	template<class T1, class T2>
	bool operator == (const shared_ptr<T1>& lhs, const shared_ptr<T2>& rhs) {
		return lhs.get() == rhs.get();
	}
	template<class T>
	bool operator == (const shared_ptr<T>& sp, nullptr_t p) {
		return sp.get() == p;
	}
	template<class T>
	bool operator == (nullptr_t p, const shared_ptr<T>& sp) {
		return sp == p;
	}
	template<class T1, class T2>
	bool operator != (const shared_ptr<T1>& lhs, const shared_ptr<T2>& rhs) {
		return !(lhs == rhs);
	}
	template<class T>
	bool operator != (const shared_ptr<T>& sp, nullptr_t p) {
		return !(sp == p);
	}
	template<class T>
	bool operator != (nullptr_t p, const shared_ptr<T>& sp) {
		return !(sp == p);
	}

	template<class T, class...Args>
	shared_ptr<T> make_shared(Args... args) {
		return shared_ptr<T>(new T(std::forward<Args>(args)...));
	}
}

#endif
相关标签: tinystl c++ stl