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));
}
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));
}
全站熱搜
留言列表