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

📄 index.htm

📁 设计模式模板源码
💻 HTM
📖 第 1 页 / 共 3 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE>Cross-Platform Design Pattern Template Library( XPDPTL )</TITLE>
<META content="text/html" http-equiv=Content-Type>
<META content="Tony Lee" name=author>
<STYLE type=text/css>
H2 {
	BORDER-TOP: 1px solid; PADDING-TOP: 4px
}
H3 {
	BORDER-TOP: 2px solid; PADDING-TOP: 4px
}
</STYLE>

<META content="MSHTML 5.00.3315.2870" name=GENERATOR></HEAD>
<BODY style="max-width: 700px">
<P 
style="BACKGROUND-COLOR: #eeffff; BORDER-BOTTOM: 1px dashed; BORDER-LEFT: 1px dashed; BORDER-RIGHT: 1px dashed; BORDER-TOP: 1px dashed; PADDING-BOTTOM: 2px; PADDING-LEFT: 2px; PADDING-RIGHT: 2px; PADDING-TOP: 2px">Cross-Platform Design Pattern Template Library( XPDPTL )<br> Last update: June 1, 2003</P>

<H3>Document Index</H3>

<UL>
  <LI><A HREF="#platforms">Installation</A></LI>
  <LI><A HREF="#introduction"> Introduction to XPDPTL</A></LI>
  <LI><A HREF="#Interface">Interface-Based Programming</A></LI>
  <LI><A HREF="#C++Event">C++ Event package</A></LI>
  <LI><A HREF="#XPDP">XP Design Pattern </A></LI>
  <LI><A HREF="#references">References</A></LI>

</UL>

<H3>Installation</H3>
<BLOCKQUOTE 
style="BACKGROUND-COLOR: #eeeeee; BORDER-BOTTOM: 1px dashed; BORDER-LEFT: 1px dashed; BORDER-RIGHT: 1px dashed; BORDER-TOP: 1px dashed; PADDING-BOTTOM: 4px; PADDING-LEFT: 4px; PADDING-RIGHT: 4px; PADDING-TOP: 4px">

The latest version of the XPDPTL is available for download below:
<a href="http://www.bearguru.com/projects/xpdptl/xpdptl.zip">xpdptl.zip</a>

<pre>
This library  comes in full source code, and all you have to do is to unpack 
it or copy the directory tree onto your hard disk , give your compiler access 
to their path, and include them appropriately in your code via #include.
Under the root directory XPDPTL you will have the following files and directories: 

index.htm ... you are reading it 
include   ... the library itself, one *.h file for each class template 
examples  ... examples demonstrates the use of the class 
</pre>
The library should work with any C++ compiler which supports templates, regardless of the operating system. It has been tested with Microsoft VC++.
<p></p>

If you run into difficulties, feel free to contact me: devguru@hotmail.com 

</BLOCKQUOTE>

<H3><A NAME="introduction">Introduction to XPDPTL</A></H3>

<H4>Welcome to XPDPTL</H4>

<BLOCKQUOTE 
style="BACKGROUND-COLOR: #eeeeee; BORDER-BOTTOM: 1px dashed; BORDER-LEFT: 1px dashed; BORDER-RIGHT: 1px dashed; BORDER-TOP: 1px dashed; PADDING-BOTTOM: 4px; PADDING-LEFT: 4px; PADDING-RIGHT: 4px; PADDING-TOP: 4px">

The Cross-Platform Design Pattern Template Library provides support for cross-platform,interface-based programming, Event package,Library subset and several commonly used design patterns in the form of C++ templates.
<p></p>

When you need a pattern such as Composite, Subject-Observer  just grab the class from the library. 


</BLOCKQUOTE>


<H4>Major Features</H4>

<BLOCKQUOTE 
style="BACKGROUND-COLOR: #eeeeee; BORDER-BOTTOM: 1px dashed; BORDER-LEFT: 1px dashed; BORDER-RIGHT: 1px dashed; BORDER-TOP: 1px dashed; PADDING-BOTTOM: 4px; PADDING-LEFT: 4px; PADDING-RIGHT: 4px; PADDING-TOP: 4px">

<ul>
<li>Cross-Platform</li>
<li>Interface-based programming</li>
<li>Event architecture </li>
<li>Library subset </li>
<li>Commonly used Design Patterns </li>
</ul>

</BLOCKQUOTE>

<H4>Dependency</H4>

<BLOCKQUOTE 
style="BACKGROUND-COLOR: #eeeeee; BORDER-BOTTOM: 1px dashed; BORDER-LEFT: 1px dashed; BORDER-RIGHT: 1px dashed; BORDER-TOP: 1px dashed; PADDING-BOTTOM: 4px; PADDING-LEFT: 4px; PADDING-RIGHT: 4px; PADDING-TOP: 4px">

It would be very useful to allow programmers to use smaller subsets of the entire XPDPTL library. Below will identify these subsets and dependency relationship: 

<ul>

<li>XPCore -- This subset contains four files. the OS adaptation layer (<a href="include/xptypes.h">xptypes.h</a>) and Interface-Based Programming supporting classes(<a href="include/GuidCast.h">GuidCast.h</a>  <a href="include/RefCount.h">RefCount.h</a>  <a href="include/CppIface.h">CppIface.h</a>). All other subsets will depend on XPCore and it will depend on no other files. <br>Classes or Interface in this subset include: <strong>IQueryGuid IRefCount CIQueryGuidImpl </strong>
</li>
<p></p>
<li>XPEvent -- This subset contains three files(<a href="include/Events/Event.h">Event.h</a>  <a href="include/Events/EventListener.h">EventListener.h</a>  <a href="include/Events/EventRouter.h">EventRouter.h</a>) to support event architecture and depends only on XPCore. <br>Classes or Interface in this subset include: <strong>IEvent IEventListener CEventListenerBase IEventRouter IEventRouterImpl CComboRouterListener CListeningRouter </strong>
</li>
<p></p>
<li>XP Design Pattern 
<ul>	 
<li>The Singleton Pattern -- This subset contains one file (<a href="include/Patterns/Singleton.h">Singleton.h</a>) and and depend on no other files.<br>Classes or Interface in this subset include: <strong>Singleton</strong>
</li>
<p></p>

<li>The Object Factory Pattern -- This subset contains one file (<a href="include/Patterns/Factory.h">Factory.h</a>) and and depends only on XPCore.<br>Classes or Interface in this subset include: <strong>CObjectFactoryBase CObjectFactory</strong>
</li>
<p></p>
<li>The Subject-Observer Pattern -- This subsets contains one file (<a href="include/Patterns/SubjectObserver.h">SubjectObserver.h</a>)and and depends only on XPCore.
<br>Classes or Interface in this subset include: <strong>IMessage ISubject IObserver ISubjectImpl </strong>
</li>
<p></p>
<li>The Iterator Pattern -- This subsets contains one file (<a href="include/Patterns/Iterator.h">Iterator.h</a>)and and depends only on XPCore.
<br>Classes or Interface in this subset include: <strong>IteratorBase Iterator </strong>
</li>

<p></p>
<li>The Composite  Pattern -- This subsets contains one file (<a href="include/Patterns/Composite.h">Composite.h</a>)and and depends only on XPCore.
<br>Classes or Interface in this subset include: <strong>CComposite</strong>
</li>

</ul>
</li>

</ul>

</BLOCKQUOTE>

<H3 ><A NAME="interface">Interface-Based Programming</A></H3>

<H4>Introduction</H4>

<BLOCKQUOTE 
style="BACKGROUND-COLOR: #eeeeee; BORDER-BOTTOM: 1px dashed; BORDER-LEFT: 1px dashed; BORDER-RIGHT: 1px dashed; BORDER-TOP: 1px dashed; PADDING-BOTTOM: 4px; PADDING-LEFT: 4px; PADDING-RIGHT: 4px; PADDING-TOP: 4px">

Interface-based programming is a popular and convenient technique frequently used in object-oriented software development. An interface is a collection of purevirtual or abstract functions that provide related functionality. An interface has no implementation and no data members. An interface defines a contract or protocol between the user of the interface and objects that implement the interface. Interfaces make a design more flexible because they reduce coupling between client code and an object’s implementation. The same client code can manipulate objects that are completely unrelated in the class hierarchy, as long as the objects provide the client with an interface it understands.

<p></p>

Interface-based programming is the cornerstone of Microsoft's Component Object Model (COM). Everything in COM is an interface. All COM interfaces are derived from the root interface IUnknown, which provides the basic services required by all interfaces. Lifetime management is the first service required by COM interfaces, and is provided through the IUnknown functions AddRef() and Release(). Runtime discovery of interfaces is the other service required by COM interfaces, and is provided through the IUnknown function QueryInterface(). The QueryInterface() function is used to interrogate an object for another interface.QueryInterface() takes a Globally Unique Identifier (GUID) and returns a pointer to an interface. It is similar to the dynamic_cast operator in C++, although it is more flexible and efficient.<br>


</BLOCKQUOTE>



<H4>IQueryGuid and guid_cast</H4>

<BLOCKQUOTE 
style="BACKGROUND-COLOR: #eeeeee; BORDER-BOTTOM: 1px dashed; BORDER-LEFT: 1px dashed; BORDER-RIGHT: 1px dashed; BORDER-TOP: 1px dashed; PADDING-BOTTOM: 4px; PADDING-LEFT: 4px; PADDING-RIGHT: 4px; PADDING-TOP: 4px">

One way to create functionality similar to QueryInterface() is to use the C++ dynamic_cast() operator. This is an effective solution if your compiler supports it (current versions of the Windows CE compiler do not support C++ RTTI). Enabling RTTI also introduces some extra overhead for every class compiled. Many developers prefer to avoid enabling RTTI, or at least want a choice in the
matter. The solution used by XPDPTL avoids the use of C++ RTTI by introducing an interface that provides a function very similar to IUnknown's QueryInterface().The IQueryGuid interface has a single method, QueryGuid() which allows the caller to pass in a GUID and get back a pointer to an interface or class. It is exactly like QueryInterface(), except that QueryGuid() is more generic.QueryInterface() is only meant to get back pointers to interfaces. QueryGuid() acts as a substitute for dynamic_cast, so it is perfectly acceptable to associate a GUID with a concrete class and then use QueryGuid() to cast pointers to that concrete class. Below shows how IQueryGuid is defined:

<pre>
class IQueryGuid
{
public:
	virtual XPBool QueryGuid(XPREFIID guid,void **ppvObj)=0;
};

</pre>

QueryGuid() is similar to QueryInterface() with a couple of notable exceptions.First, QueryGuid() returns true if the interface is supported by the object and false if it fails. The most important difference is that QueryGuid() does not make any assumptions about reference counting. Although QueryInterface() always increments the reference count on an interface before returning it to the caller, QueryGuid() does not. This is because IQueryGuid does not have any reference counting methods. It is perfectly valid to use IQueryGuid for casting interfaces and classes that do not support reference counting.


Below shows a class that implements IQueryGuid:

<pre>

#define XP_IANIMAL_IID     \
{ 0x8a181176, 0xb5e8, 0x4c7e, { 0x97, 0xfc, 0xa2, 0x2e, 0x57, 0x7, 0xe6, 0x5f } };

class IAnimal : public IQueryGuid
{
public:
	virtual void Eat() = 0;
	virtual void Sleep() = 0;
	virtual void Reproduce() = 0;
	static const XPIID& IID() { static XPIID iid = XP_IANIMAL_IID; return iid; }
};

class CCow : public IAnimal
{
public:
	virtual XPBool QueryGuid(XPIID guid,void **ppvObj)
	{
		*ppvObj = 0;
		if (guid == IAnimal::IID() )
		*ppvObj = static_cast<IAnimal*>(this);
		else if (guid == IQueryGuid::IID() )
		*ppvObj = static_cast<IQueryGuid*>(this);
		return (*ppvObj != 0);
	}
	virtual void Eat(){// chew some grass}
	virtual void Sleep(){// sleep standing up?}
	virtual void Reproduce(){// not a pretty sight}
};

</pre>

The guid_cast template function makes QueryGuid() type safe, so it is more like dynamic_cast and easier to use. It acts like dynamic_cast and is implemented by calling QueryGuid(). Below shows how guid_cast is used:

<pre>

void MakeAnimalEat(IQueryGuid* pObj)
{
	IAnimal* pAnimal = guid_cast<IAnimal*>(pObj);
	if (pAnimal)
		pAnimal->Eat();
}

</pre>

</BLOCKQUOTE>


<H4>GUID Maps</H4>

<BLOCKQUOTE 
style="BACKGROUND-COLOR: #eeeeee; BORDER-BOTTOM: 1px dashed; BORDER-LEFT: 1px dashed; BORDER-RIGHT: 1px dashed; BORDER-TOP: 1px dashed; PADDING-BOTTOM: 4px; PADDING-LEFT: 4px; PADDING-RIGHT: 4px; PADDING-TOP: 4px">
Implementing QueryGuid() is a tedious and repetitive task, so using macros to write most of the code is convenient. A GUID map is a set of macros that collectively implement the QueryGuid() function. They are nearly identical to ATL's BEGIN_COM_MAP and END_COM_MAP macros, which implement QueryInterface().Below shows how you can use GUID maps to implement QueryGuid():

<pre>
class CCow : public IAnimal
{
	public:
		BEGIN_GUID_MAP(CCow)
			GUID_ENTRY(IAnimal)
			GUID_ENTRY(IQueryGuid)
		END_GUID_MAP
};
</pre>

The macros expand out to the same implementation of CCow::QueryGuid() shown in the previous sample.
In certain cases, a class may inherit an interface from more than one base class.That will produce an ambiguous reference in the GUID map that you must resolve with the GUID_ENTRY2 macro. Below shows the GUID_ENTRY2 macro used to resolve an ambiguous reference to IQueryGuid:

<pre>

class IFood : public IQueryGuid
{
	public:
		virtual void BeConsumed() = 0;
};

class CCow : public IAnimal, public IFood
{
	public:
		BEGIN_GUID_MAP(CCow)
			GUID_ENTRY(IAnimal)
			GUID_ENTRY2(IQueryGuid, IAnimal)
		END_GUID_MAP
};

</pre>

</BLOCKQUOTE>


<H4>	Reference Counting</H4>

<BLOCKQUOTE 
style="BACKGROUND-COLOR: #eeeeee; BORDER-BOTTOM: 1px dashed; BORDER-LEFT: 1px dashed; BORDER-RIGHT: 1px dashed; BORDER-TOP: 1px dashed; PADDING-BOTTOM: 4px; PADDING-LEFT: 4px; PADDING-RIGHT: 4px; PADDING-TOP: 4px">

Reference counting is another service that is useful in interface-based programming.COM requires that all interfaces are reference counted, but for our C++ interfaces reference counting is optional. The interface IRefCount defines the AddRef() and Release() methods needed to perform reference counting. The signatures of AddRef() and Release() in IRefCount are identical to the signatures in IUnknown.

XPDPTL provides a default implementation of IRefCount that you can mix into a concrete class. The CRefCountImpl is a template class that takes the base class as a template parameter and implements reference counting. Remember that the implementation of reference counting provided by CRefCountImpl is not threadsafe. Support cross-platform  threadsafe is beyond this library.<br>

Below modifies our cow so that it supports reference counting:

<pre>
class IAnimal : public IQueryGuid, public IRefCount
{
	public:
		virtual void Eat() = 0;
		virtual void Sleep() = 0;
		virtual void Reproduce() = 0;
};
class IFood : public IQueryGuid, public IRefCount
{
	public:
		virtual void BeConsumed() = 0;
};
class CCow : public CRefCountImpl<IAnimal>, public IFood
{
	public:

⌨️ 快捷键说明

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