smart_ptr.hpp
#pragma once
#include <cstdint>
#include <memory>
template <class T>
class smart_ptr {
private:
T* _obj;
uint32_t _count;
void add();
void dec();
protected:
public:
smart_ptr(T* obj_);
smart_ptr(const smart_ptr&);
smart_ptr& operator =(const smart_ptr&);
~smart_ptr();
};
template <class T>
inline smart_ptr<T>::smart_ptr(T* obj_) : _obj(obj_), _count(1) {}
template <class T>
inline smart_ptr<T>::smart_ptr(const smart_ptr& that) {
memcpy_s(this, sizeof(smart_ptr), &that, sizeof(smart_ptr));
add();
}
template <class T>
inline smart_ptr<T>& smart_ptr<T>::operator =(const smart_ptr& that) {
if (&that == this) {
return *this;
}
dec();
memcpy_s(this, sizeof(smart_ptr), &that, sizeof(smart_ptr));
add();
return *this;
}
template <class T>
inline smart_ptr<T>::~smart_ptr() {
dec();
}
template <class T>
inline void smart_ptr<T>::add() {
_MT_INCR(_count);
}
template <class T>
inline void smart_ptr<T>::dec() {
if (_MT_DECR(_count) == 0) {
delete _obj;
}
}
採用引用計數的方式進行管理,簡單明瞭
改進版:
#pragma once
#include <cstdint>
#include <memory>
template <class T>
class smart_ptr {
private:
T* _obj;
uint32_t _count;
protected:
public:
smart_ptr(T* obj_);
smart_ptr(const smart_ptr&);
smart_ptr& operator =(const smart_ptr&);
void operator =(void*);
T* operator ->();
~smart_ptr();
void add();
void dec();
uint32_t count();
};
template <class T>
inline smart_ptr<T>::smart_ptr(T* obj_) : _obj(obj_), _count(1) {}
template <class T>
inline smart_ptr<T>::smart_ptr(const smart_ptr& that) : _count(0) {
if (that._count == 0) {
return;
}
memcpy_s(this, sizeof(smart_ptr), &that, sizeof(smart_ptr));
add();
}
template <class T>
inline smart_ptr<T>& smart_ptr<T>::operator =(const smart_ptr& that) {
if (&that == this || that._count == 0) {
return *this;
}
dec();
memcpy_s(this, sizeof(smart_ptr), &that, sizeof(smart_ptr));
add();
return *this;
}
template<class T>
inline void smart_ptr<T>::operator=(void* other) {
dec();
}
template<class T>
inline T* smart_ptr<T>::operator->() {
return _obj;
}
template <class T>
inline smart_ptr<T>::~smart_ptr() {
dec();
}
template <class T>
inline void smart_ptr<T>::add() {
_MT_INCR(_count);
}
template <class T>
inline void smart_ptr<T>::dec() {
if (_MT_DECR(_count) == 0) {
delete _obj;
}
}
template <class T>
inline uint32_t smart_ptr<T>::count() {
return _count;
}
再次改進版(實際使用已無錯誤):
#pragma once
#include <cstdint>
#include <memory>
#define del_ptr(ptr) if (ptr) { delete ptr; ptr = nullptr; }
template <class T>
class smart_ptr {
private:
bool _free;
T* _obj;
long* _count;
protected:
public:
smart_ptr();
smart_ptr(T* obj_);
smart_ptr(const smart_ptr&);
smart_ptr& operator =(const smart_ptr&);
smart_ptr& operator =(smart_ptr&&);
bool operator ==(const smart_ptr&);
T& operator *();
T* operator ->();
~smart_ptr();
void add();
void dec();
long count() const;
};
template <class T>
inline smart_ptr<T>::smart_ptr() : _free(false), _obj(nullptr), _count(new long(0)) {}
template <class T>
inline smart_ptr<T>::smart_ptr(T* obj_) : _free(false), _obj(obj_), _count(new long(1)) {}
template <class T>
inline smart_ptr<T>::smart_ptr(const smart_ptr& that) {
operator =(that);
}
template <class T>
inline smart_ptr<T>& smart_ptr<T>::operator =(const smart_ptr& that) {
if (&that == this || that.count() == 0) {
return *this;
}
dec();
memcpy_s(this, sizeof(smart_ptr), &that, sizeof(smart_ptr));
add();
return *this;
}
template<class T>
inline smart_ptr<T>& smart_ptr<T>::operator =(smart_ptr&& that) {
operator =(that);
return *this;
}
template<class T>
inline bool smart_ptr<T>::operator ==(const smart_ptr& that) {
return this == &that;
}
template<class T>
inline T& smart_ptr<T>::operator *() {
return *_obj;
}
template<class T>
inline T* smart_ptr<T>::operator->() {
return _obj;
}
template <class T>
inline smart_ptr<T>::~smart_ptr() {
dec();
_free = true;
}
template <class T>
inline void smart_ptr<T>::add() {
if (!_free && _count) {
_InterlockedIncrement(reinterpret_cast<volatile long*>(_count));
}
}
template <class T>
inline void smart_ptr<T>::dec() {
if (_free || !_count) {
return;
}
if (*_count == 0) {
del_ptr(_count);
return;
}
if (_InterlockedDecrement(reinterpret_cast<volatile long*>(_count)) == 0) {
del_ptr(_count);
if (!_obj) {
return;
}
delete _obj;
}
}
template <class T>
inline long smart_ptr<T>::count() const {
return (!_free && _count) ? *_count : 0;
}