1、首先描述一下指針值的含義:
假設內存值的序列是這樣描述的 : 我們定義一個 0 ~ 50 的正整數序列。
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,1,0,0,8,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0
它第15號數值是 1,第18號數值是8。
由此,我們可以想象 “序號15” 就是指針,指針的值就是 “序號15位置上描述了一個變量1”。
爲了方便表示:我們定義變量 x 的位置就在 “序號15”上,y序號的位置就在”序號18”上。
所以其值相加:x + y = 1 + 8 = 9;
爲了刻意記錄這些序號位置,我們又創建了一張表專門記錄這些序號,它的描述方式假設是這樣的:
(爲了文章的簡潔性:我們將”描述這些變量的值” 用 ”n(x)” 來表式, “&” 表示向上取這些值的序號位置 )
&n0 ,&n1 ,&n2 ,&n3 ,&n4 ,&n5 ,&n6 ,&n7 ,&n8 ,&n9 ,
&n10,&n11,&n12,&n13,&n14,&n15,&n16,&n17,&n18,&n19,
&n20,&n21,&n22,&n23,&n24,&n25,&n26,&n27,&n28,&n29,
&n30,&n31,&n32,&n33,&n34,&n35,&n36,&n37,&n38,&n39,
&n40,&n41,&n42,&n43,&n44,&n45,&n46,&n47,&n48,&n49
“序號15”位置上描述了一個變量1,我們可以理解成,記錄 “序號15值”的變量是1,其變量名是”n15”,記錄n15的位置是”&n15”(第15號地址);
因 ”&表示獲取序號” ,那麼它的反作用 ”*表示取序號下的值”所以:
*(&n15) = n15 = 1;
擴展理解【假設: *n15 = *(&1); (這裏是把n15 的值當做一個地址來使用,它表示第1號地址的值)】
2、由於本文章強調的是動態函數指針傳遞,那麼我們進入正題:(關於指針的其他問題可以在評論區提問)
//例子1 運行基本實例 (動態函數指針的傳遞)
class T_object
{
public:
T_object(){
}
virtual ~T_object(){
}
int func(void* p){
int step = *((int*)p);
step += 2;
return step;
}
};
void main()
{
T_object t;
int (T_object::* _pfunc) (void*) = &T_object::func;
int step = 0;
for (size_t i = 0; i < 100; i++)
{
step = (t.*_pfunc)(&step);
printf("running T_object::func,%d\n", step);
}
}
將動態函數指針賦予 _pfunc 作爲載體,它需要 t 對象完成實例化執行。
執行方法如下:
step = (t.*_pfunc)(&step);
step = t.func(&step);
這兩個等式表達方式是一樣的。
(關於用途舉例:可以在主類不採用多態的方式承載多套實現的方法,這裏引用敲門磚,希望大家能夠舉一反三)
//例子2 動態函數指針的應用
class T_object
{
public:
T_object(){
}
virtual ~T_object(){
}
int func(void* p){
int step = *((int*)p);
step += 2;
return step;
}
//new coode begin
int func1(void* p) {
int step = *((int*)p);
step += 3;
return step;
}
int func2(void* p) {
int step = *((int*)p);
step += 4;
return step;
}
//new coode end
};
void main()
{
T_object t;
int (T_object::* _pfunc) (void*) = &T_object::func;
_pfunc = &T_object::func1;
_pfunc = &T_object::func2;
int step = 0;
for (size_t i = 0; i < 100; i++)
{
step = (t.*_pfunc)(&step);
printf("running T_object::func,%d\n", step);
}
}
以上調用僅表示它最基本的原始代碼展現,方便認知閱讀:
(爲了提高閱讀使用性,下面我們開始優化變型操作)
將函數式包含在內,使調用方更易理解及調用;
//例子3 函數指針作爲參數傳遞
class T_object
{
public:
T_object(){
m_pfunc = NULL;
}
virtual ~T_object() {
}
int func(void* p){
int step = *((int*)p);
step += 2;
return step;
}
void addfunc(int(T_object::* pfunc)(void*))
{
m_pfunc = pfunc;
}
int Do(int step)
{
if (m_pfunc != NULL)
{
step = (this->*m_pfunc)(&step);
}
return step;
}
int(T_object::* m_pfunc)(void*);
};
void main()
{
T_object t;
//添加函數指針 (對外的方法及調用)
t.addfunc(&T_object::func);
int step = 0;
for (size_t i = 0; i < 100; i++){
step = t.Do(step);
printf("running T_object::func,%d\n", step);
}
}
根據此方法,可以動態的實施類函數的調用。
將函數指針式再簡化,函數指針作爲命名類型參數傳遞:
//例子 4 函數指針作爲命名類型參數傳遞
class T_object
{
public:
//定義函數類
typedef int(T_object::* PFUNC)(void*);
T_object() {
m_pfunc = NULL;
}
virtual ~T_object() {
}
int func(void* p) {
int step = *((int*)p);
step += 2;
return step;
}
void addfunc(PFUNC pfunc)
{
m_pfunc = pfunc;
}
int Do(int step)
{
if (m_pfunc != NULL)
{
step = (this->*m_pfunc)(&step);
}
return step;
}
PFUNC m_pfunc;
};
void main()
{
T_object t;
//添加函數指針 (對外的方法及調用)
t.addfunc(&T_object::func);
int step = 0;
for (size_t i = 0; i < 100; i++){
step = t.Do(step);
printf("running T_object::func,%d\n", step);
}
}
以上是關於類函數傳參的調用方式,可以通過該方法實現很多功能,內容太多本次就不一一舉例了。