C++線程安全的智能指針

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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章