程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> c++ 基於Policy 的 模板編程

c++ 基於Policy 的 模板編程

編輯:C++入門知識

在沒真正接觸c++ 模板編程之前,真的沒有想到c++ 還可以這麼用,最大的感觸是:太靈活了,太強大了。最初接觸模板威力還是在Delta3d中,感覺裡面的模板使用實在是靈活與方便,特別是dtAI中使用了大量的模板,大大增強了庫的可擴展性。


本文基於《c++ 設計新思維》 而寫。


先看一段代碼:

#include 
#include 
#include 
using namespace std;
//--------------------------------------------------------------------------------
/////////Widget類型
class SliderWidget
{
public:
	SliderWidget()
	{
		std::cout<<"Slider Widget created"<
class OpNewCreateor
{
public:
	static T* create()
	{
		return new T;
	}
protected:
	~OpNewCreateor(){}
};

template 
class MallocCreator
{
public:
	static T* create()
	{
		void * buf = std::malloc(sizeof(T));
		if(!buf) return 0;

		return new(buf) T;
	}
protected:
	~MallocCreator(){}
};

template 
class PrototypeCreator
{
public:
	PrototypeCreator(T* pObj = 0)
		:pPrototype(pObj)
	{

	}
	T* create()
	{
		return pPrototype ? pPrototype->clone() : 0;
	}
	T* getPrototype(){return pPrototype;}
	void setPrototype(T*pObj){pPrototype = pObj;}

protected:
	~PrototypeCreator(){}
private:
	T* pPrototype;
};
//--------------------------------------------------------------------------------
//存儲widget容器類型
template
class ContainerVec
{
public:
	void push(T* widget)
	{
		mVecContainer.push_back(widget);
	}
protected:
	~ContainerVec(){}

private:
	std::vector mVecContainer;//Vector容器
};

template 
class ContainerList
{
public:
	void push(T* widget)
	{
		mListContainer.insert(widget);
	}
protected:
	~ContainerList(){}
private:
	std::list mListContainer;//List容器
};
//--------------------------------------------------------------------------------
//--------widget管理類
template <
	class T,
	template class CreationPolicy = MallocCreator,
	template class Container = ContainerVec
>
class WidgetManager :public CreationPolicy					
{
public:
	typedef CreationPolicy BaseClass;
	T* create()
	{
		 T* tmp =  BaseClass::create();
		 mContainer.push(tmp);
		 return tmp;
	}


private:
	Container mContainer;
};
//policies的最大的威力來自於它們可以相互混合搭配
//--------------------------------------------------------------------------------
typedef WidgetManager BoxWidgetManager;
typedef WidgetManager SliderWidgetManager;
//--------------------------------------------------------------------------------
int main()
{
	BoxWidgetManager boxWidgetManager;

	BoxWidget * boxWidget = boxWidgetManager.create();


	system(	"pause");
}


什麼是基於Policy編程

1. Policies機制是由templates和多繼承組成 。

2. 而所謂policy,乃用來定義一個class或class template的接口,該接口由 “內隱型別定義 inner type definition),成員函數、或成員變量之一或全部組成。

3. policy接口和一般傳統的class接口(virtual函數)不同,它比較 松散,這是因為policies 是語法導向(syntax oriented)而非標記導向(signature oriented)。也就是說上面的 createpolicy 明確定義的是:怎樣的語法構造符合其所規范的class”,而非“必須實作出哪些函數”。createpolicy 並沒有規范create()是virtual 還是static,它只要求必須定義出create函數。

4. 如果一個模板使用了policies,我們稱其為host class ,如上面的widgetmanager。



Policy class 的析構函數

1. 大部分情況下,host class 會以 public 繼承 方式從某些policies 派生而來,因此 使用者可以將一個host class 轉換為一個 policy class ,並於稍後delete 該指針。

除非policy class 定義了一個 虛析構函數(virtual destructor) ,否則 delete一個指向policy class 指針,會有問題(最起碼 這樣會使得 host class 的析構函數沒調用)

2. 如果把policy class 的析構函數 定義成虛析構函數,會妨礙policy的靜態連接特性,也會影響執行效率。(引入一份vptr,也會帶來額外開銷),所以盡量避免虛析構函數

3. 許多policy class 並無數據成員,純粹只是一個規范行為,policy class應該采用一個輕便而有效率的解法------定義一個non-vritual protected 析構函數。這樣保證了只有繼承者才能摧毀這個policy對象。


通過不完全具化而獲得選擇性機能

1. 意思是: 如果class template 有一個成員函數並未曾被用到,它就不會被編譯器所具體實現出來。


以policy class 定制結構

通過policy class 不但可以定制行為,如要能夠create,而且還可以定制結構。這個重要的性質使得policy-based design 超越了簡單的型別泛化(type genericity),後者對於容器(container class )效力卓越。 (如上面的container policy)



下一步: c++ template traits


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved