由淺入深講解動態類函數指針

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);
	}
}

以上是關於類函數傳參的調用方式,可以通過該方法實現很多功能,內容太多本次就不一一舉例了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章