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

📄 composite.h

📁 设计模式模板源码
💻 H
字号:
/////////////////////////////////////////////////////////////////////////////
// Composite.h : Composite design pattern
//


#include <list>
#include <algorithm>
#include "..\GuidCast.h"
#include "Iterator.h"



// Disable the warning that complains about the symbols name length 


//@doc 

//@class CComposite |
/*
	Implements the composite design pattern
*/
//@tcarg typename | _Component | Type of the elements in the composite structure
//@tcarg XPIID | guid | XPIID that identifies the Composite interface among all the interfaces implemented by an element
template <typename _Component, const XPIID* _guid>
class CComposite:
	public IQueryGuid
{
	typedef CComposite<_Component, _guid> _thisClass;
	typedef std::list<_Component* > Children;

	class CompIterator:
		public Iterator<Children>
	{
	public:
		friend class _thisClass;
		explicit CompIterator(Children& acoll): Iterator<Children>(acoll) {}
	};


public:

	typedef IteratorBase<_Component*> Iterator;

	// Composite design pattern operations

	//@cmember
	// Returns the number of nodes directly contained in this node
	int GetChildrenCount () const;
	//@cmember
	// Returns the total number of nodes contained by this node and its children
	int GetAllDescendantsCount () const;


	//@cmember
	// Returns this node's parent
	_Component* GetParent() const;
	//@cmember
	// Sets the parent node
	void SetParent(_Component* pComp);
	//@cmember
	// Returns the root of the composite tree
	_Component* GetRoot();

	//@cmember
	// Adds a node as a child of this node
	int AddChild(_Component* pComp);
	//@cmember
	// Removes a child node
	int RemoveChild(_Component* pComp);

	//@cmember
	// Returns an iterator of this node's children
	Iterator* GetChildIterator();

protected:

	CComposite(): m_pParent(NULL) {}
	virtual ~CComposite() {}

protected:
	// Composite design pattern implementation
	Children m_Children;
	_Component* m_pParent;

};



//@mfunc int | CComposite<lt<gt | GetChildrenCount | 
// Returns the number of nodes directly contained in this node
//@rdesc Count of child nodes
template <typename _Component, const XPIID* _guid>
int 
CComposite<_Component, _guid>::GetChildrenCount (
) const
{
	int nCount = 0;
	nCount = (int)m_Children.size();
	return nCount;
}


//@mfunc int | CComposite<lt<gt | GetAllDescendantsCount | 
// Returns the total number of nodes contained by this node and its children
//@rdesc Count of child nodes
//@comm GetAllDescendantsCount recursively counts the number of nodes in this
// node and its children.
template <typename _Component, const XPIID* _guid>
int 
CComposite<_Component, _guid>::GetAllDescendantsCount (
) const
{
	int nCount = GetChildrenCount();
	Children::const_iterator i;
	for (i = m_Children.begin(); i != m_Children.end(); ++i) {
#if _MSC_VER > 1100
		const _thisClass* pComposite = guid_cast<const _thisClass*, _guid>(*i);
		nCount += pComposite->GetAllDescendantsCount();
#else
		const _thisClass* pComposite;
		if ((*i)->QueryGuid(*_guid, (void**) &pComposite))
		{
			nCount += pComposite->GetAllDescendantsCount();
		}
#endif
	}
	return nCount;
}


//@mfunc _Component* | CComposite<lt<gt | GetParent | 
// Returns this node's parent node
//@rdesc Pointer to parent node
template <typename _Component, const XPIID* _guid>
_Component* 
CComposite<_Component, _guid>::GetParent (
) const
{ 
	return m_pParent; 
}


//@mfunc void | CComposite<lt<gt | SetParent | 
// Sets this node as child of the given node
//@parm _Component* | pComp | Parent node
template <typename _Component, const XPIID* _guid>
void 
CComposite<_Component, _guid>::SetParent (
	_Component* pComp
)
{ 
	m_pParent = pComp; 
}


//@mfunc _Component* | CComposite<lt<gt | GetRoot | 
// Returns the root of tree-like structure the composite defines
//@rdesc Root node of the composite
template <typename _Component, const XPIID* _guid>
_Component* 
CComposite<_Component, _guid>::GetRoot (
) 
{
	_thisClass* pRoot = this;
	_Component* pParent = 0;
	do {
		pParent = pRoot->GetParent();
		if (pParent) {
#if _MSC_VER > 1100
			pRoot = guid_cast<_thisClass*, _guid>(pParent);
#else
			pParent->QueryGuid(*_guid, (void**) &pRoot);
#endif
		}
	} while (pParent);

	return guid_cast<_Component*>(pRoot);
}


//@mfunc int | CComposite<lt<gt | AddChild | 
// Adds the given node to this node's list of children 
//@rdesc The number of children this node contains after inserting the new one
//@parm _Component* | pComp | New child node
template <typename _Component, const XPIID* _guid>
int 
CComposite<_Component, _guid>::AddChild (
	_Component* pComp
) 
{
	const UUID& uuid = __uuidof(CComposite);
#if _MSC_VER > 1100
	_thisClass* pNode = guid_cast<_thisClass*, _guid>(pComp);
	_thisClass* pParent = guid_cast<_thisClass*, _guid>(pNode->GetParent());
#else
	_thisClass* pNode;
	_thisClass* pParent;
	pComp->QueryGuid(*_guid, (void**)&pNode);
	pNode->GetParent()->QueryGuid(*_guid, (void**)&pParent);
#endif
	if (pParent) {
		if (pParent == this) {
			return GetChildrenCount();	// already a child!
		}
		else {
			pParent->RemoveChild(pComp);
		}
	}

	// Add the child node
	try {
		m_Children.push_back(pComp);
		pNode->SetParent(guid_cast<_Component*>(this));
	}
	catch (std::exception& ) {
		return -1;
	}

	return GetChildrenCount();
}


//@mfunc int | CComposite<lt<gt | RemoveChild | 
// Removes the given node from this node's list of children 
//@rdesc The number of children this node contains after removing the one requested
//@parm _Component* | pComp | Node to remove
template <typename _Component, const XPIID* _guid>
int 
CComposite<_Component, _guid>::RemoveChild (
	_Component* pComp
)
{
	if (!pComp) {
		return -1;
	}

#if _MSC_VER > 1100
	_thisClass* pNode = guid_cast<_thisClass*, _guid>(pComp);
#else
	_thisClass* pNode;
	pComp->QueryGuid(*_guid, (void**)&pNode);
#endif

	// Remove the child
	try {
		Children::iterator pos = std::find(m_Children.begin(), m_Children.end(), pComp);
		if (pos != m_Children.end()) {
			m_Children.erase(pos);
			pNode->SetParent(NULL);
		}
	}
	catch (std::exception& ) {
		return -1;
	}

	return GetChildrenCount();
}


//@mfunc Iterator* | CComposite<lt<gt | GetChildIterator | 
// Returns an iterator that allows traversing this node's collection of child nodes
//@rdesc Iterator for collection of children
template <typename _Component, const XPIID* _guid>
CComposite<_Component, _guid>::Iterator*
CComposite<_Component, _guid>::GetChildIterator()
{
	return new CompIterator(m_Children);
}

⌨️ 快捷键说明

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