100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > C++指向类成员的函数指针

C++指向类成员的函数指针

时间:2023-11-11 01:14:33

相关推荐

C++指向类成员的函数指针

指向类成员函数的函数指针

定义:类成员函数指针(member function pointer),是 C++ 语言的一类指针数据类型,用于存储一个指定类具有给定的形参列表与返回值类型的成员函数的访问信息。

基本上要注意的有两点:

1、函数指针赋值要使用 &

2、使用 .* (实例对象)或者 ->*(实例对象指针)调用类成员函数指针所指向的函数

下面看两个例子:

A) 类成员函数指针指向类中的非静态成员函数

对于 nonstatic member function (非静态成员函数)取地址,获得该函数在内存中的实际地址

对于 virtual function(虚函数), 其地址在编译时期是未知的,所以对于 virtual member function(虚成员函数)取其地址,所能获得的只是一个索引值

//指向类成员函数的函数指针#include <iostream>#include <cstdio>using namespace std;class A{public:A(int aa = 0):a(aa){}~A(){}void setA(int aa = 1){a = aa;}virtual void print(){cout << "A: " << a << endl;}virtual void printa(){cout << "A1: " << a << endl;}private:int a;};class B:public A{public:B():A(), b(0){}B(int aa, int bb):A(aa), b(bb){}~B(){}virtual void print(){A::print();cout << "B: " << b << endl;}virtual void printa(){A::printa();cout << "B: " << b << endl;}private:int b;};int main(void){A a;B b;void (A::*ptr)(int) = &A::setA;A* pa = &a;//对于非虚函数,返回其在内存的真实地址printf("A::set(): %p\n", &A::setA);//对于虚函数, 返回其在虚函数表的偏移位置printf("B::print(): %p\n", &A::print);printf("B::print(): %p\n", &A::printa);a.print();a.setA(10);a.print();a.setA(100);a.print();//对于指向类成员函数的函数指针,引用时必须传入一个类对象的this指针,所以必须由类实体调用(pa->*ptr)(1000);a.print();(a.*ptr)(10000);a.print();return 0;}

执行以上代码,输出结果为:

A::set(): 0x8048a38

B::print(): 0x1

B::print(): 0x5

A: 0

A: 10

A: 100

A: 1000

A: 10000

B) 类成员函数指针指向类中的静态成员函数

#include <iostream>using namespace std;class A{public://p1是一个指向非static成员函数的函数指针void (A::*p1)(void);//p2是一个指向static成员函数的函数指针void (*p2)(void);A(){/*对**指向非static成员函数的指针**和**指向static成员函数的指针**的变量的赋值方式是一样的,都是&ClassName::memberVariable形式**区别在于:**对p1只能用非static成员函数赋值**对p2只能用static成员函数赋值****再有,赋值时如果直接&memberVariable,则在VS中报"编译器错误 C2276"**参见:/zh-cn/library/850cstw1.aspx*/p1 =&A::funa; //函数指针赋值一定要使用 &p2 =&A::funb;//p1 =&A::funb;//error//p2 =&A::funa;//error//p1=&funa;//error,编译器错误 C2276//p2=&funb;//error,编译器错误 C2276}void funa(void){puts("A");}static void funb(void){puts("B");}};int main(){A a;//p是指向A中非static成员函数的函数指针void (A::*p)(void);(a.*a.p1)(); //打印 A//使用.*(实例对象)或者->*(实例对象指针)调用类成员函数指针所指向的函数p = a.p1;(a.*p)();//打印 AA *b = &a;(b->*p)(); //打印 A/*尽管a.p2本身是个非static变量,但是a.p2是指向static函数的函数指针,**所以下面这就话是错的!*/// p = a.p2;//errorvoid (*pp)(void);pp = &A::funb;pp(); //打印 Breturn 0;}

总结

类成员函数指针与普通函数指针不是一码事。前者要用 .* 与 ->* 运算符来使用,而后者可以用 * 运算符(称为"解引用"dereference,或称"间址"indirection)。普通函数指针实际上保存的是函数体的开始地址,因此也称"代码指针",以区别于 C/C++ 最常用的数据指针。而类成员函数指针就不仅仅是类成员函数的内存起始地址,还需要能解决因为 C++ 的多重继承、虚继承而带来的类实例地址的调整问题,所以类成员函数指针在调用的时候一定要传入类实例对象。

原文连接

/w3cnote/cpp-func-pointer.html

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。