⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smart_ptr.h

📁 一个开源的Flash 播放器,可以在Windows/Linux 上运行
💻 H
字号:
// smart_ptr.h	-- by Thatcher Ulrich <tu@tulrich.com> 2003// This source code has been donated to the Public Domain.  Do// whatever you want with it.// Smart (ref-counting) pointer classes.  Uses "intrusive" approach:// the types pointed to must have add_ref() and drop_ref() methods.// Typically this is done by inheriting from a ref_counted class,// although the nice thing about templates is that no particular// ref-counted class is mandated.#ifndef SMART_PTR_H#define SMART_PTR_H#include "base/tu_config.h"#include "base/utility.h"// A smart (strong) pointer asserts that the pointed-to object will// not go away as long as the strong pointer is valid.  "Owners" of an// object should keep strong pointers; other objects should use a// strong pointer temporarily while they are actively using the// object, to prevent the object from being deleted.template<class T>class smart_ptr{public:	smart_ptr(T* ptr)		:		m_ptr(ptr)	{		if (m_ptr)		{			m_ptr->add_ref();		}	}	smart_ptr() : m_ptr(NULL) {}	smart_ptr(const smart_ptr<T>& s)		:		m_ptr(s.m_ptr)	{		if (m_ptr)		{			m_ptr->add_ref();		}	}	~smart_ptr()	{		if (m_ptr)		{			m_ptr->drop_ref();		}	}//	operator bool() const { return m_ptr != NULL; }	void	operator=(const smart_ptr<T>& s) { set_ref(s.m_ptr); }	void	operator=(T* ptr) { set_ref(ptr); }//	void	operator=(const weak_ptr<T>& w);	T*	operator->() const { assert(m_ptr); return m_ptr; }	T*	get_ptr() const { return m_ptr; }	bool	operator==(const smart_ptr<T>& p) const { return m_ptr == p.m_ptr; }	bool	operator!=(const smart_ptr<T>& p) const { return m_ptr != p.m_ptr; }	bool	operator==(T* p) const { return m_ptr == p; }	bool	operator!=(T* p) const { return m_ptr != p; }	// Provide work-alikes for static_cast, dynamic_cast, implicit up-cast?  ("gentle_cast" a la ajb?)private:	void	set_ref(T* ptr)	{		if (ptr != m_ptr)		{			if (m_ptr)			{				m_ptr->drop_ref();			}			m_ptr = ptr;			if (m_ptr)			{				m_ptr->add_ref();			}		}	}//	friend weak_ptr;	T*	m_ptr;};// Helper for making objects that can have weak_ptr's.class weak_proxy{public:	weak_proxy()		:		m_ref_count(0),		m_alive(true)	{	}	// weak_ptr's call this to determine if their pointer is valid or not.	bool	is_alive() const { return m_alive; }	// Only the actual object should call this.	void	notify_object_died() { m_alive = false; }	void	add_ref()	{		assert(m_ref_count >= 0);		m_ref_count++;	}	void	drop_ref()	{		assert(m_ref_count > 0);		m_ref_count--;		if (m_ref_count == 0)		{			// Now we die.			delete this;		}	}private:	// Don't use these.	weak_proxy(const weak_proxy& w) { assert(0); }	void	operator=(const weak_proxy& w) { assert(0); }	int	m_ref_count;	bool	m_alive;};// A weak pointer points at an object, but the object may be deleted// at any time, in which case the weak pointer automatically becomes// NULL.  The only way to use a weak pointer is by converting it to a// strong pointer (i.e. for temporary use).//// The class pointed to must have a "weak_proxy* get_weak_proxy()" method.//// Usage idiom://// if (smart_ptr<my_type> ptr = m_weak_ptr_to_my_type) { ... use ptr->whatever() safely in here ... }template<class T>class weak_ptr{public:	weak_ptr()		:		m_ptr(0)	{	}	weak_ptr(T* ptr)		:		m_ptr(0)	{		operator=(ptr);	}	weak_ptr(const smart_ptr<T>& ptr)	{		operator=(ptr.get_ptr());	}	// Default constructor and assignment from weak_ptr<T> are OK.	void	operator=(T* ptr)	{		m_ptr = ptr;		if (m_ptr)		{			m_proxy = m_ptr->get_weak_proxy();			assert(m_proxy != NULL);			assert(m_proxy->is_alive());		}		else		{			m_proxy = NULL;		}	}	void	operator=(const smart_ptr<T>& ptr) { operator=(ptr.get_ptr()); }	// Conversion to smart_ptr.	operator smart_ptr<T>()	{		check_proxy();		return smart_ptr<T>(m_ptr);	}	bool	operator==(T* ptr) { check_proxy(); return m_ptr == ptr; }	bool	operator==(const smart_ptr<T>& ptr) { check_proxy(); return m_ptr == ptr.get_ptr(); }private:	void check_proxy()	// Set m_ptr to NULL if the object died.	{		if (m_ptr)		{			assert(m_proxy != NULL);			if (m_proxy->is_alive() == false)			{				// Underlying object went away.				m_proxy = NULL;				m_ptr = NULL;			}		}	}	smart_ptr<weak_proxy>	m_proxy;	T*	m_ptr;};// Example ref_counted class:// #if 0ref_counted{	mutable int	m_ref_count	mutable weak_proxy* m_weak_proxy;	ref_counted()		:		m_ref_count(0),		m_weak_proxy(0)	{	}	// @@ usual ref-counted stuff here for add_ref() and drop_ref()	virtual ~ref_counted()	{		assert(m_ref_count == 0);		if (m_weak_proxy)		{			m_weak_proxy->notify_object_died();			m_weak_proxy->drop_ref();			m_weak_proxy = NULL;		}	}	weak_proxy* get_weak_proxy() const	{		if (m_weak_proxy == NULL)		{			m_weak_proxy = new weak_proxy;			m_weak_proxy->add_ref();		}	}};#endif // 0#endif // SMART_PTR_H// Local Variables:// mode: C++// c-basic-offset: 8 // tab-width: 8// indent-tabs-mode: t// End:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -