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

📄 smartptr.h

📁 遗传算法做图像的模式匹配
💻 H
📖 第 1 页 / 共 2 页
字号:

/*! \file SmartPtr.h
    \brief This file contains declaration and implementation of template classes and datatypes that handles smart pointers used by the library.
*/

/*
 * 
 * website: http://www.coolsoft-sd.com/
 * contact: support@coolsoft-sd.com
 *
 */

/*
 * Genetic Algorithm Library
 * Copyright (C) 2007-2008 Coolsoft Software Development
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 */

#ifndef __GA_SMART_PTR_H__
#define __GA_SMART_PTR_H__

#include "Platform.h"
#include "Threading.h"

namespace Common
{
	template <typename T>
	class GaSmartPtr;

	/// <summary><c>GaSmartStorage</c> template class provides reference-counting for smart pointers.
	/// <c>GaSmartStorage</c> objects holds address of used data and number of references (smart pointers) which point to the data.
	/// Object of this class as well as the data are destroyed and memory is freed when there are no more references which points to the data.
	/// Arrays cannot be used with this class. This class has no built-in synchronizator, so <c>LOCK_OBJECT</c> and <c>LOCK_THIS_OBJECT</c> macros
	/// cannot be used with instances of this class, but all public method and operators are thread-safe. </summary>
	template <typename T>
	class GaSmartStorage
	{

	friend class GaSmartPtr<T>;

	private:

		/// <summary>Holds number of references (smart pointers) to data guarded by this object.</summary>
		mutable int _count;

		/// <summary>Pointer to user data.</summary>
		T* _data;

	public:

		/// <summary><c>MakeInstance</c> makes new reference-counting object for data at address data. This method is thread-safe.</summary>
		/// <param name="data">pointer to data. <c>data</c> cannot be an array.</param>
		/// <returns>Method returns smart pointer which points to data and use newly created object for reference-counting.</returns>
		static GaSmartPtr<T> GACALL MakeInstance(T* data) { return GaSmartPtr<T>( new GaSmartStorage<T>( data ) ); }

		/// <summary><c>MakeInstance</c> makes new reference-counting object for data at address data. This method is thread-safe.</summary>
		/// <param name="data">pointer to data. <c>data</c> cannot be an array.</param>
		/// <returns>Method returns reference to newly created object for reference-counting.</returns>
		static GaSmartStorage<T>* GACALL MakeInstanceDirect(T* data) { return new GaSmartStorage<T>( data ); }

		// Increase count of references which point to this location
		/// <summary>This method increments number of references to the data. <c>AddReference</c> method is called when smart pointer
		/// is set to point to the location. This method is thread-safe.</summary>
		/// <param name="location">pointer to location which is incremented.</param>
		/// <returns>Method returns new number of references which still points to the data.</returns>
		static int GACALL AddReference(GaSmartStorage<T>* location) { return location ? ATOMIC_INC( location->_count ) : 0; }

		// Decrease count of references which point to this location
		/// <summary>This method decrements number of references, if that number reaches 0, the data is destroyed and memory is freed.
		/// <c>RemoveReference</c> method is called when smart pointers are destructed or when set to point to new location.
		/// This method is thread-safe.</summary>
		/// <param name="location">pointer to location which is decremented.</param>
		/// <returns>Method returns new number of references which still points to the data.</returns>
		static int GACALL RemoveReference(GaSmartStorage<T>* location)
		{
			if( location )
			{
				int new_count = ATOMIC_DEC( location->_count );

				// no more references?
				if( !new_count )
					delete location;

				return new_count;
			}

			return 0;
		}

		/// <summary>Initializes object for counting references to data located at <c>data</c> address. </summary>
		/// <param name="data">pointer to user data. <c>data</c> cannot be an array.</param>
		GaSmartStorage(T* data) : _count(0), 
			_data(data) { }

		/// <summary>Destructor is called when there are no more references which points to the data. Destructor frees memory used by the data. </summary>
		~GaSmartStorage()
		{
			if( _data )
				delete _data;
		}

		/// <summary>This method is thread-safe.</summary>
		/// <returns>Method returns pointer to user data.</returns>
		inline T* GACALL GetData() const { return _data; }

		/// <summary>This method is thread-safe.</summary>
		/// <returns>Method returns number of references (smart pointers) which points to this location.</returns>
		inline int GACALL GetCount() const { return _count; }

	};// END CLASS DEFINITION GaSmartStorage

	/// <summary><c>GaSmartPtr</c> template class wraps C++ raw pointers, and takes over responsibility of managing the allocated memory.
	/// Smart pointer holds address of user data and reference to an object which is responsible for counting number of references to data,
	/// when there are no instances of <c>GaSmartPtr</c> pointing to location of the data (reference count of the location reaches 0),
	/// object is destroyed and memory used by the object is freed. Memory management by <c>GaSmartPtr</c> class is thread-safe,
	/// but after dereferencing smart pointer to access the data, it cannot be guaranteed that memory will not be freed if some other thread
	/// changes dereferenced pointer. Implemented smart pointers have some limitations:
	/// <br>1. Dynamically allocated arrays cannot be managed by GaSmartPtr class.
	/// <br>2. Circular references can cause memory leakage.
	///
	/// This class has no built-in synchronizator, so <c>LOCK_OBJECT</c> and <c>LOCK_THIS_OBJECT</c> macros cannot be used with instances of
	/// this class, but all public method and operators are thread-safe.</summary>
	/// <param name="T">type of data to which smart pointer references.</param>
	template <typename T>
	class GaSmartPtr
	{

	private:

		/// <summary>Guards smart pointer against concurrent changes.</summary>
		mutable volatile unsigned long _lock;

		/// <summary>Holds address of user data.</summary>
		T* _data;

		/// <summary>Pointer to object which holds reference-count and address of data.</summary>
		GaSmartStorage<T>* _location;

	public:

		/// <summary>This constructor makes new reference to data that are managed by <see cref="GaSmertStorage" />.
		/// Creation of smart pointer and counting of references is thread-safe.</summary>
		/// <param name="storage">reference to object responsible for reference-counting.</param>
		GaSmartPtr(GaSmartStorage<T>* storage) : _lock(0)
		{
			Lock();

			// add new reference to smart location
			GaSmartStorage<T>::AddReference( storage );

			_location = storage;
			_data = _location ? _location->_data : NULL;

			Unlock();
		}

		/// <summary>This constructor make instance of <see cref="GaSmartStorage" /> and binds unmanaged memory to the smart storage.
		/// If the given memory is already managed by this mechanism, it can cause unexpected results.
		/// Creation of smart pointer and counting of references is thread-safe.</summary>
		/// <param name="rawPtr">raw pointer to data.</param>
		GaSmartPtr(T* rawPtr) : _lock(0)
		{
			Lock();

			GaSmartStorage<T>* location = GaSmartStorage<T>::MakeInstanceDirect( rawPtr );
			
			// add new reference to smart location
			GaSmartStorage<T>::AddReference( location );

			_location = location;
			_data = _location ? _location->_data : NULL;

			Unlock();
		}

		/// <summary>Copy constructor makes new reference to data to which <c>ptr</c> points.
		/// Creation of smart pointer and counting of references is thread-safe.</summary>
		/// <param name="ptr">reference to smart pointer which should be copied.</param>

⌨️ 快捷键说明

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