您的位置:首页 > 其它

普通函数,成员函数,静态成员函数与【指针】

2010-01-23 15:13 405 查看
函数指针
原创:CmdHack
时间:2010年1月24日1:46:43
研究的对象 研究的内容
1:普通函数指针 函数指针的申明
2:成员函数指针 函数指针的赋值

3:静态成员函数指针 函数指针的调用

以下是对普通函数指针的分析
#include "stdafx.h"
#include <iostream.h>
int Add(int a, int b)
{
return a+b;
}
int main(int argc, char* argv[])
{
//普通函数指针的声明
//////////////////////////////////////////////////////////////////////////
//方法:
//将函数的声明复制过来int Add(int a, int b)
//然后后边加";"号  再然后将Add换成(*pXX)就可以了
//注意:参数a,b可以不要 但是参数的类型要保留
//比如可以写成int (*pAdd)(int , int) = NULL
//////////////////////////////////////////////////////////////////////////
int (*pAdd)(int a, int b) = NULL;
################################################################################
这个地方需要特别注意   该函数指针的类型是int (*)(int a, int b)    //将变量去掉就是类型
为了简洁明了 我们常常用typedef为该类型取一个好看的名字
例如:typedef int (*pFunAdd)(int a, int b)
这样pFunAdd和int (*)(int a, int b)便等价了  以后用到 int (*)(int a, int b)的时候都用
pFunAdd表示
比如这里 最好写成
typedef int (*pFunAdd)(int a, int b);
pFunAdd pAdd = NULL;
################################################################################

//普通函数的定义
//////////////////////////////////////////////////////////////////////////
//方法:
//如下很清楚 直接将函数的地址(函数名字) 赋值给函数指针变量就可以了
//注意:写成 pAdd = &Add也对 跟数组一样  对他们的名称取地址还是那个地址
//////////////////////////////////////////////////////////////////////////
pAdd = Add;

//函数的调用
//////////////////////////////////////////////////////////////////////////
//方法:
//指针变量p(参数1, 参数2,...) 如下pAdd(2,5)
//当然也可以写成(*pAdd)(2,5)   这样的解释是
//(*pAdd) 对函数指针变量取内容自然就是函数了  然后后边加上参数 自然没错
//////////////////////////////////////////////////////////////////////////
cout << pAdd(2,5) << endl;
return 0;
}


以下是对成员函数指针的分析

#include "stdafx.h"
#include <string.h>
#include <iostream.h>

class CCstudent
{
private:
char m_szName[32];
public:
CCstudent(const char* szName)
{
Iint();
SetName(szName);
}
~CCstudent()
{
}
Iint()
{
if (!m_szName)
{
memset(m_szName, 0, 32);
}
}

void SetName(const char* szName)
{
if (strlen(szName) > 32)
{
cout << "字符串过长" << endl;
}
if (szName == NULL)
{
cout << "字符串为空" << endl;
}
strcpy(m_szName, szName);
}

const char* GetName()
{
return m_szName;
}

};
int main(int argc, char* argv[])
{
typedef void (CCstudent::*Funtype_Normal)(const char*);
CCstudent TheStu("Mr.董");
cout << TheStu.GetName() << endl;

//////////////////////////////////////////////////////////////////////////
//成员函数指针
//////////////////////////////////////////////////////////////////////////

//成员函数指针的声明
//直接将成员函数的生命拷贝过来    void SetName(const char* szName);
//然后将SetName  写成(作用域*指针变量名称) 如下(CCstudent::*pFunSet)
//////////////////////////////////////////////////////////////////////////
void (CCstudent::*pFunSet)(const char*) = NULL;
//////////////////////////////////////////////////////////////////////////
//注意变量是pFunSet  变量的类型是void (CCstudent::*pFunSet)(const char*)
//编程时这个类型太复杂 应该用typedef重新定义 如下:
//typedef void (CCstudent::*Funtype_Normal)(const char*)
//然后上边就可以改写成 Funtype_Normal pFunSet = NULL;
//////////////////////////////////////////////////////////////////////////

//成员函数定义
//这个地方直接将 变量名 = 函数名 就可以
//注意: 指针变量声明的时候已经声明了函数的类型
pFunSet = CCstudent::SetName;

//成员函数指着的调用
特别强调  如成员函数的调用方式是_thiscall类型  所以调用之前必须要用到对象
所以成员函数指针的调用也必须使用到对象

(TheStu.*pFunSet)("董");
语法:
这里可以写成(对象名.*成员函数指针变量名)(参数);
也可以写  成(对象指针->*成员函数指针变量名)(参数);
这里的*的作用是与成员函数的调用以区别 而且不要遗漏()();

cout << TheStu.GetName() << endl;
return 0;
}


以下是对静态成员函数指针的分析

#include "stdafx.h"
#include <iostream.h>
#include <string.h>
class  student
{
protected:
char m_szName[32];    //姓名
static int m_stuCount;    //学员个数
public:
student(const char* szName)
{
//对szName的判断省略
strcpy(m_szName, szName);
++m_stuCount;
}
~student()
{
--m_stuCount;
}

//统计学员个数
static int StuCount()
{
return m_stuCount;
}
};

int student::m_stuCount = 0;    //静态成员初始化

int main(int argc, char* argv[])
{
//这个地方不要写成
//typedef static int (student::*FunstaticType)();

typedef int (*FunstaticType)();
student theStu1("贝克汉姆");
student theStu2("鲁尼");

//静态成员函数指针的声明
//static int (*pStaticFun)();
FunstaticType pStaticFun = NULL;

//静态成员函数指针的定义;
//...注意 作用域的问题
//pStaticFun = student::StuCount;
pStaticFun = student::StuCount;

//静态成员函数指针的调用
cout << "学员一共有" << pStaticFun() << endl;
return 0;
}

注意  成员函数的调用方式是_thiscall调用方式
静态成员函数的调用方式是_cdecl调用方式

静态成员函数的指针声明的时候跟普通函数一样
不要加作用域
但又区别于普通函数指针的是
在静态成员函数指针定义的时候需要加作用域


最后总结

语法总结
比如有int Add(int x,int y)    //普通函数
{
return Return x+y;
};

class student
{
public:
void SetData(const char* Name);    //成员函数
static int StuCount();    //静态成员函数
}

普通函数指针
申明:
int (*pFunAdd)(int x,int y) = NULL;
定义
pFunAdd = Add;
调用
pFunAdd(int 10, int 20);

成员函数指针
申明:
//	void (类名::*指针变量名)(const char* Name) [作用域]
void (student::*pFunClassSetData)(const char* Name) = NULL;
定义:
//  函数指针变量名 = 函数名(一常量地址)
//  由于变量在申明的时候已经加上了作用域 所以这里不需要再加作用域了
pFunClassSetData = SetData;
调用:
//(对象名.指针变量)(参数)  不要写成对象名.指针变量(参数)
student TheStu;
(TheStu.pFunClassSetData)();
特别注意:
成员函数的调用约定有别于普通函数和静态成员函数的_cdecl调用方式
成员函数的调用方式是_thiscall调用方式   所以在调用之前【必须】
要有对象

语法:
这里可以写成(对象名.*成员函数指针变量名)(参数);
也可以写  成(对象指针->*成员函数指针变量名)(参数);
这里的*的作用是与成员函数的调用以区别 而且不要遗漏()();

静态成员函数指针
申明:
//函数名换成“(*变量名)” 就可以了 不要加作用域
static int (*pStaticFun)() = NULL;
定义:
//函数指针变量名 = 作用域::函数名
pStaticFun = student::StuCount;
调用:
//函数指针变量名(参数);
pStaticFun();

特别注意:
静态成员函数指针在生命的时候不要加作用域
在定义的时候函数之前要加作用域
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: