经过长时间的学习终于可以开始tinystl的仿(chao)写工作了,本文参考了这位大神的github,坦白讲我只是补充了注释,因为tinystl的代码真的非常经典而我又没什么这种大型项目的经验,所以只能这样做,不过相信能够有助于大家的学习
#强烈建议按顺序阅读本专栏
cowptr:原生指针
阅读这篇文章了解原生指针 泛型指针 智能指针
本文实现的原生指针并没有达到应有的效果,仅仅实现了基本功能
cowptr.h
#pragma once
#ifndef _COWPTR_H_
#define _COWPTR_H_
#include "Memory.h"
namespace mySTL {
template<class T>
class cow_ptr;
namespace Detail {
template <class T>
class proxy {
public:
explicit proxy(cow_ptr<T> *const cp) :cp_(cp) {}
proxy(const proxy<T>&) = default;
proxy& operator = (const proxy<T>&) = default;
const T& operator *()const;
T& operator *();
const T *operator ->()const;
T *operator ->();
cow_ptr<T>& operator = (const T& val);
operator T()const;
private:
cow_ptr<T> *cp_;
};
}
//未能完全模拟原生指针操作,只供参考,详情见单元测试
template<class T>
class cow_ptr {
public:
typedef T element_type;
private:
template<class _T>
using proxy = Detail::proxy < _T >;
public:
explicit cow_ptr(T *p = nullptr);
template<class D>
cow_ptr(T *p, D d);
cow_ptr(const cow_ptr& cp);
cow_ptr& operator = (const cow_ptr& cp);
const proxy<element_type> operator *()const;
proxy<element_type> operator *();
const proxy<element_type> operator ->()const;
proxy<element_type> operator ->();
element_type *get();
const element_type *get()const;
operator bool() const;
private:
shared_ptr<element_type> ptr_;
public:
template<class T1, class T2>
friend bool operator == (const cow_ptr<T1>& cp1, const cow_ptr<T2>& cp2);
template<class T>
friend bool operator == (const cow_ptr<T>& cp, nullptr_t p);
template<class T>
friend bool operator == (nullptr_t p, const cow_ptr<T>& cp);
template<class T1, class T2>
friend bool operator != (const cow_ptr<T1>& cp1, const cow_ptr<T2>& cp2);
template<class T>
friend bool operator != (const cow_ptr<T>& cp, nullptr_t p);
template<class T>
friend bool operator != (nullptr_t p, const cow_ptr<T>& cp);
template<class _T>
friend class Detail::proxy;
};
template<class T, class... Args>
cow_ptr<T> make_cow(Args...args) {
return cow_ptr<T>(new T(std::forward<Args>(args)...));
}
}
#include "Detail\COWPtr.impl.h"
#endif
cowptr.impl.h
#pragma once
#ifndef _COWPTR_IMPL_H_
#define _COWPTR_IMPL_H_
namespace mySTL {
namespace Detail {
template<class T>
const T& proxy<T>::operator *()const {
return *(cp_->ptr_);
}
template<class T>
//将原生指针转化为share指针再返回
T& proxy<T>::operator *() {
auto t = *(cp_->ptr_);
cp_->ptr_ = make_shared<T>(t);
return *(cp_->ptr_);
}
template<class T>
const T *proxy<T>::operator ->()const {
return cp_->ptr_.operator->();
}
//将原生指针转化为share指针再返回
template<class T>
T *proxy<T>::operator ->() {
auto t = *(cp_->ptr_);
cp_->ptr_ = make_shared<T>(t);
return cp_->ptr_.operator->();
}
//转化为share指针再返回
template<class T>
cow_ptr<T>& proxy<T>::operator = (const T& val) {
cp_->ptr_ = make_shared<T>(val);
return *cp_;
}
template<class T>
proxy<T>::operator T()const { return *(cp_->ptr_); }
}
//默认构建为空
template<class T>
cow_ptr<T>::cow_ptr(T *p = nullptr) :ptr_(p) {}
template<class T>
template<class D>
cow_ptr<T>::cow_ptr(T *p, D d) : ptr_(p, d) {}
template<class T>
cow_ptr<T>::cow_ptr(const cow_ptr& cp) {
ptr_ = cp.ptr_;
}
template<class T>
cow_ptr<T>& cow_ptr<T>::operator = (const cow_ptr& cp) {
if (this != &cp) {
ptr_.decrease_ref();
ptr_ = cp.ptr_;
}
return *this;
}
template<class T>
typename cow_ptr<T>::element_type *cow_ptr<T>::get() {
return ptr_.get();
}
template<class T>
const typename cow_ptr<T>::element_type *cow_ptr<T>::get()const {
return ptr_.get();
}
template<class T>
cow_ptr<T>::operator bool()const {
return ptr_ != nullptr;
}
template<class T>
const typename cow_ptr<T>::proxy<T> cow_ptr<T>::operator *()const {
return proxy<T>(const_cast<cow_ptr *const>(this));
}
template<class T>
typename cow_ptr<T>::proxy<T> cow_ptr<T>::operator *() {
return proxy<T>(this);
}
template<class T>
const typename cow_ptr<T>::proxy<T> cow_ptr<T>::operator ->()const {
return proxy<T>(const_cast<cow_ptr *const>(this));
}
template<class T>
typename cow_ptr<T>::proxy<T> cow_ptr<T>::operator ->() {
return proxy<T>(this);
}
template<class T1, class T2>
bool operator == (const cow_ptr<T1>& cp1, const cow_ptr<T2>& cp2) {
return cp1.ptr_ == cp2.ptr_;
}
template<class T>
bool operator == (const cow_ptr<T>& cp, nullptr_t p) {
return cp.ptr_ == p;
}
template<class T>
bool operator == (nullptr_t p, const cow_ptr<T>& cp) {
return cp == p;
}
template<class T1, class T2>
bool operator != (const cow_ptr<T1>& cp1, const cow_ptr<T2>& cp2) {
return !(cp1 == cp2);
}
template<class T>
bool operator != (const cow_ptr<T>& cp, nullptr_t p) {
return !(cp == p);
}
template<class T>
bool operator != (nullptr_t p, const cow_ptr<T>& cp) {
return !(cp == p);
}
}
#endif