类成员函数指针区别于用法

通常的函数指针大家已经非常熟悉了。但我们今天讨论一下类成员函数指针的用法。

今天我们来看一下成员函数指针,加入我们想要声明一个 void CTest::Show()成员函数指针类型,那么我们一般的做法是:

typedef void(CTest::*pShow)();

从上面可以看出一些和一般函数指针类型不同的地方。让我们把他和一般的函数声明比较一下。下面是一般的函数声明:

typedef void(*pShow)();

我们可以看出成员函数指针和一般函数指针的不同,那就是成员函数指针声明时加上类限制。这会起到什么作用呢?和类成员函数一样,那就是编译器会在编译的时候在函数指针对应的函数调用中加上this指针。所以类成员函数不能单独调用,一定要注意。必须与类对象配合调用。

 

下面是一个简单的成员函数指针类型的使用例子:

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

using namespace std;
class Test

{

 int sum;

public:

 Test():sum(0){}

 int Add(int a,int b) {return (sum = a + b);}

 void Show() {cout<<"Show()";}

};

 

 

//////////////////////////////////////////////////////////cpp//////////////////////////////////////////////////////////////////////////

 

 

typedef void(Test::*pShow)();
typedef int(Test::*pAdd)(int,int);

int _tmain(int argc, _TCHAR* argv[])

{

 Test t;

 pShow Show=&Test::Show;
 pAdd  Add=&Test::Add;

 (t.*Show)();
 cout<<(t.*Add)(2,5);

}

结果:Show()7

注意其中特别的语法:

1:给指针变量赋值时,要在用来赋值的成员函数名前面加'&'符号。

2:注意(t.*Add)(2,5)可不能能写成t.*Add(2,5);因为括号的优先级比*高。所以要写成(t.*Add)(2,5)或者(t.Add)(2,5)。后者之所以可以,因为函数名本身可以当地址,但C++同时也支持&函数名为取函数地址。这关系到如果看待函数名以处理函数指针的重要问题。

 

既然说到成员函数指针的那么,我们很可能会想到它是否具有向类的函数一样的特殊性质,特别是虚函数?是的,成员函数指针就有虚函数的特性。看下例:

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

using namespace std;
class A
{
public:
 virtual void Show() {cout<<"A";}
};

class B:public A
{
public :
 void Show() {cout<<"B";}
};

 

//////////////////////////////////////////////////////////cpp//////////////////////////////////////////////////////////////////////////

 

 

typedef void(A::*pShow)();

int _tmain(int argc, _TCHAR* argv[])

{

 B t;

 pShow Show=(pShow)&A::Show;
 pShow Show=(pShow)&B::Show;

 (t.Show)();
 cin.get();

}

结果:BB

 

通过结果可以看出,虽然声明的基类的虚函数指针,但是函数指针调用时还是根据调用对象来相应的函数,颇像虚函数。所以基类成员函数指针可以根据运行时对象的类型来确定的对应的函数调用。

 

但其中有一个容易忽略的语法:

基类指针=派生类函数地址,这种隐式赋值是不行。也就是说

pShow Show=&B::Show;

编译时不通过的,也就是说C++认为将派生类成员函数名赋给基类成员函数指针是可能存在问题的。可能你会想,我们经常将派生类对象给基类指针啊,

是啊,不过两者不是一回事,考虑的角度不同。

 

前者的解释:基类的函数布局(个数)是派生类的函数布局的子集。所以基类的函数赋给派生类的函数指针时,因为派生类肯定有(public的基类函数)此函数,所以赋值很安全。反过来,你想有可能会出现问题。

后者的解释:基类所做的操作涉及的数据成员不会超出派生类的范围。所以把派生类对象给基类指针,基类来处理没问题。也很安全。反过来呢,你也知道,很危险滴!

 

所以在使用成员函数指针时大家还需多多注意。

时间: 2024-09-30 12:44:39

类成员函数指针区别于用法的相关文章

深入类的成员函数指针

先看这样一段代码   class test { public:      test(int i){ m_i=i;}      test(){};      void hello()     {          printf("hello/n");     } private:     int m_i; }; int main() {  test *p=new test();  p->hello();  p=NULL;  p->hello(); }   结果是: hello

成员函数指针与高性能的C++委托 (Member Function Pointers and the Fastest Possible C++ Delegates)

标准C++中没有真正的面向对象的函数指针.这一点对C++来说是不幸的,因为面向对象的指针(也叫做"闭包(closure)"或"委托(delegate)")在一些语言中已经证明了它宝贵的价值.在Delphi (Object Pascal)中,面向对象的函数指针是Borland可视化组建库(VCL,Visual Component Library)的基础.而在目前,C#使"委托"的概念日趋流行,这也正显示出C#这种语言的成功.在很多应用程序中,&qu

C++ 如何获取类成员函数地址?

C语言中可以用函数地址直接调用函数:     void print ()       {          printf ("function print");       }       typdef void (*fun)();       fun f = print;       f(); C++中类非静态成员函数必须通过实例去调用,C++中类成员函数调用:     class test       {       public:       void print ()     

实例解析C++中类的成员函数指针_C 语言

C语言的指针相当的灵活方便,但也相当容易出错.许多C语言初学者,甚至C语言老鸟都很容易栽倒在C语言的指针下.但不可否认的是,指针在C语言中的位置极其重要,也许可以偏激一点的来说:没有指针的C程序不是真正的C程序. 然而C++的指针却常常给我一种束手束脚的感觉.C++比C语言有更严格的静态类型,更加强调类型安全,强调编译时检查.因此,对于C语言中最容易错用的指针,更是不能放过:C++的指针被分成数据指针,数据成员指针,函数指针,成员函数指针,而且不能随便相互转换.而且这些指针的声明格式都不一样:

C++中类成员函数指针详解

原文出处:点击打开链接       在C++中类成员函数指针是一种比较特别的指针,尽管直接使用类成员函数的情况不太多,但是还是有必要详解一下这类指针.       具体语法       首先说明一下类成员函数指针的声明方式:        Return_Type (Class_Name::* pointer_name) (Argument_List); Return_Type: member function return type. Class_Name: name of the class

谈函数指针(全局/类成员函数)和函数对象

函数指针(全局函数/类成员函数).函数对象(Function object) 一. 函数指针类型为全局函数. #include "stdafx.h"#include <iostream>using namespace std;class TestAction;typedef void (*fp)(int); void Drink(int i){ cout<<"No. "<<i<<" drink..."

类的成员函数指针的使用方法

函数指针主要的目的是实现与运用相互分离,类的成员函数封装在类里面,运行需要相应的对象来调用,所以在调用这个类的成员函数时候,需要类的函数地址和这个类的对象.     以下是实现的类:     class A    {    public:void DoSth(){printf("A-DoSth");}    };    以下是调用的类:     typedef void (A::*PFun)(void);//声明类的函数指针     class B    {    public:   

c++中string类成员函数c_str()的用法_C 语言

1.string类成员函数c_str()的原型: const char *c_str()const;//返回一个以null终止的c字符串 2.c_str()函数返回一个指向正规c字符串的指针,内容和string类的本身对象是一样的,通过string类的c_str()函数能够把string对象转换成c中的字符串的样式; 3.操作c_str()函数的返回值时,只能使用c字符串的操作函数,如:strcpy()等函数.因为,string对象可能在使用后被析构函数释放掉,那么你所指向的内容就具有不确定性.

C++普通函数指针与成员函数指针实例解析_C 语言

C++的函数指针(function pointer)是通过指向函数的指针间接调用函数.相信很多人对指向一般函数的函数指针使用的比较多,而对指向类成员函数的函数指针则比较陌生.本文即对C++普通函数指针与成员函数指针进行实例解析. 一.普通函数指针 通常我们所说的函数指针指的是指向一般普通函数的指针.和其他指针一样,函数指针指向某种特定类型,所有被同一指针运用的函数必须具有相同的形参类型和返回类型. int (*pf)(int, int); // 声明函数指针 这里,pf指向的函数类型是int (