close

 






/**
*
*	C++ 中的函數指針模板
*
*	所謂的函數指針模板就是指向函數模板的函數指針.
*
*[問題描述]
*	定義了一類函數模板, 而且這函數模板有共同的街口, 即一致的參數列表, 那麼如何定義一個函數指針,
*	使這個函數指針可以指向這一類中的所有函數模板呢?
*
*  [一]
*	我們先了解一件事情, 在C++裡面, 函數模板僅僅是一個用來生成函數的代碼塊而已,
*	他本身並沒有實體, 有就是沒有與 "未被實例化的那些程式" 相對應的程式代碼塊,
*	所以也就無法對其取地址( 因為就不存在啊, 怎麼會有地址?),
*	所以只有在用具體類型代替模板參數, 對該模板進行實例化以後才能有函數實體.
*
*	而這些函數指針要指向函數的入口地址, 那麼既然函數模板沒有具體的內存地址, 那麼指向函數模板的函數指針如何得到地址呢?
*	所以所謂的 " 函數模板指針 " 這個定義是無法通過以下的方法實現的:
*			templatevoid (*sample)(T& );
*
*  [二]
*	所以就要用以下的方法來實現, 讓模板類與模板函數再一起
*/

 



#include 
using namespace std;


class CA {
public :
	/*
		由於我們在寫這些工具類的方法, 通常我們都是用類的靜態成員函數,
		靜態成員函數的訪問和調用, 是通過ClassType::StaticMemberFunction來實現
	*/
	//static int Sum(int a, int b);
	int Sum(int a, int b)
	{
		return a + b;
	}
};



class CB {
public:
	//static float Sum(float a, float b);
	float Sum(float a, float b)
	{
		return a + b;
	}
};




template 
class CC {
public:
	// function pointer type template
	/*
		會使用到typedef 是因為要讓邊義氣明白pClassFunc是一個函數指針類型名(不是函數指針),
		這個類型的函數指針可以指向一個函數,
		被指向的這個函數必須滿足以下條件: 返回值為 ParaType,
		參數列表為 (ParaType, ParaType), 而且是一個定義在ClassType類中的成員函數.
		注意: 需要再作用域標示符號後面, 函數指針類型名之前, 一定要加上*(dereference),
		表明要定義的是函數指針類型.
		如果不加上這個操作符號, 那這邊就會變成對一個名叫pClassFunc的函數成員進行泛化了,
		那麼typedef關鍵字的存在似乎就沒有意義了
	*/
	typedef ParaType(ClassType::*pClassFunc)(ParaType, ParaType);

	// function pointer method
	ParaType Result(ClassType* pClassType, pClassFunc fun, ParaType a, ParaType b) {
		/*
			使用這個函數指真實, 需要創建一個類的實例, 對於函數指針的fun所指向的成員函數, 需要由實例來完成調用.
		*/
		return (pClassType->*fun)(a, b);
	}
};

void main()
{
	CA ca;
	CC cc;
	int a = 3;
	int b = 4;
	printf("A+B : %d \n", cc.Result(&ca, &CA::Sum, a, b));


	CB cb;
	CCfcc;
	float fa = 3.3f;
	float fb = 4.6f;

	printf("A+B : %f \n", fcc.Result(&cb, &CB::Sum, fa, fb));
}


image

 

C++ 11之後可以這樣







/**
*
*	C++ 中的函數指針模板
*
*	所謂的函數指針模板就是指向函數模板的函數指針.
*
*[問題描述]
*	定義了一類函數模板, 而且這函數模板有共同的街口, 即一致的參數列表, 那麼如何定義一個函數指針,
*	使這個函數指針可以指向這一類中的所有函數模板呢?
*
*  [一]
*	我們先了解一件事情, 在C++裡面, 函數模板僅僅是一個用來生成函數的代碼塊而已,
*	他本身並沒有實體, 有就是沒有與 "未被實例化的那些程式" 相對應的程式代碼塊,
*	所以也就無法對其取地址( 因為就不存在啊, 怎麼會有地址?),
*	所以只有在用具體類型代替模板參數, 對該模板進行實例化以後才能有函數實體.
*
*	而這些函數指針要指向函數的入口地址, 那麼既然函數模板沒有具體的內存地址, 那麼指向函數模板的函數指針如何得到地址呢?
*	所以所謂的 " 函數模板指針 " 這個定義是無法通過以下的方法實現的:
*			templatevoid (*sample)(T& );
*
*  [二]
*	所以就要用以下的方法來實現, 讓模板類與模板函數再一起
*/

 



#include 
using namespace std;


class CA {
public :
	/*
		由於我們在寫這些工具類的方法, 通常我們都是用類的靜態成員函數,
		靜態成員函數的訪問和調用, 是通過ClassType::StaticMemberFunction來實現
	*/
	static int Sum(int a, int b);
	
};
int CA::Sum(int a, int b)
{
	return a + b;
}


class CB {
public:
	static float Sum(float a, float b);
};

float CB::Sum(float a, float b)
{
	return a + b;
}




//template 
template 
class CC {
public:
	// function pointer type template
	/*
		會使用到typedef 是因為要讓邊義氣明白pClassFunc是一個函數指針類型名(不是函數指針),
		這個類型的函數指針可以指向一個函數,
		被指向的這個函數必須滿足以下條件: 返回值為 ParaType,
		參數列表為 (ParaType, ParaType), 而且是一個定義在ClassType類中的成員函數.
		注意: 需要再作用域標示符號後面, 函數指針類型名之前, 一定要加上*(dereference),
		表明要定義的是函數指針類型.
		如果不加上這個操作符號, 那這邊就會變成對一個名叫pClassFunc的函數成員進行泛化了,
		那麼typedef關鍵字的存在似乎就沒有意義了
	*/
	//typedef ParaType(ClassType::*pClassFunc)(ParaType, ParaType);
	typedef ParaType(*pClassFunc)(ParaType, ParaType);


	// function pointer method
// 	ParaType Result(ClassType* pClassType, pClassFunc fun, ParaType a, ParaType b) {
// 		/*
// 			使用這個函數指真實, 需要創建一個類的實例, 對於函數指針的fun所指向的成員函數, 需要由實例來完成調用.
// 		*/
// 		return (pClassType->*fun)(a, b);
// 	}
	ParaType Result(pClassFunc fun,ParaType a, ParaType b) {
		
 		return (*fun)(a, b);
 	}
};

void main()
{
	CA ca;
	CCcc;
	int a = 3;
	int b = 4;
	printf("A+B : %d \n", cc.Result(CA::Sum, a, b));


	CB cb;
	CCfcc;
	float fa = 3.3f;
	float fb = 4.6f;

	printf("A+B : %f \n", fcc.Result(CB::Sum, fa, fb));
}

image

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 Eric 的頭像
    Eric

    一個小小工程師的心情抒發天地

    Eric 發表在 痞客邦 留言(0) 人氣()