再谈C++类成员函数的指针问题
class A{
public:
void a(){}
};
出问题的原因就是有人一相情愿的声明
void (*test)=&A::a //Error:Cannot convert 'void (A::*)()' to 'void (*)()'
这就出了问题,因为类A没有实例,当然成员函数void a()就没有一个确定的地址。解决的办法也比较简单:
1.把void a()声明为static。不过这是个最笨最没人愿意干的办法,class A的一
般成员都不能访问了,那把void a()放在class A里面干什么呢?一般情况下不可取。
2.把指针声明改成void (A::*)test,那也就轻松过关。不过调用的时候却得找一个实例才能嫁得出去。
似乎问题已经完了,却还有一个问题。如果给出了实例
A aa;
又当如何呢?
CSDN有不少回答是这样的:
test=&(aa.a)甚至于test=aa.a
可是这样编译能通过吗?至少我没做到,诸位有什么办法。
我们继续。有人骂过这样用的人,真是无聊。其实这种用法相当普遍。在Borland
的C++ Builder里,比如一个TButton,它的OnClick就是一个函数指针,往往是指
向TForm的子类的一个成员函数。这时候上面的方法2又出了问题。方法2是预先知
道了类名才声明的函数指针,而我们的Form都是继承至TForm,类名根本就不知道
,而Borland却做到了这一点。激动地想看看Borland的高超水平,仔细看过,大
失所望。Borland增加了一个关键词__closure,以此声明的函数指针可以自动绑
定一个实例,调用就轻而易举了。
void (__closure *test)=aa.a;
test();
可怜我们这些遵守ANSI C++的却没办法改变编译器。
要预先得知还没有编出来的类的名字,我们的手段当然是template。借助模板,
这个问题也可以得到解决。可惜模板只对函数和类而言,为一个指针再来打造一
个类,是不是太浪费了一点?而且一但确定了,我们却不能再随心所欲地更改这
个指针,我们只能让这个指针在这个类里兜圈子,还要传递实例的参数,麻烦!
那我们怎么才能做到像Borland一样的效果呢?CSDN里有人是这么说的
“在函数入口处通过访问堆栈得到函数入口地址”
我的水平还不到这一步,我做不到。我也不知道这样干对于BC和VC是否同样有效
,但我相信C++能有一个圆满的答复,希望诸位能加入讨论一下。
相关推荐
C++ 一般(普通)函数指针、类成员函数指针,用法区别,以及强制转换
博文地址:https://blog.csdn.net/maoyeahcom/article/details/107106680
C++指向类成员函数的指针详细解析
由于这几天在开发中要用到函数指针,所以就整理了一下关于函数指针的概念
C++ 指向类成员的指针
前面曾写过一篇恼人的函数指针(一),总结了普通函数指针的声明、定义以及调用,还有函数指针数组,函数指针用作返回值等。但是作为C++的研读,我发现我漏掉了一个最重要的内容,就是指向类成员的指针,这里将做相应补充(相关代码测试环境为vs 2010)。 指向类成员的指针总的来讲可以分为两大类四小类(指向数据成员还是成员函数,指向普通成员还是静态成员),下面一一做介绍: 一、指向类的普通成员的指针(非静态) 1、指向类成员函数的指针 简单的讲,指向类成员函数的指针与普通函数指针的区别在于,前者不仅要匹配函数的参数类型和个数以及返回值类型,还要匹配该函数指针所属的类类型。总结一下,比较以下几点: a)参
c++类成员函数作为回调函数
c++类成员函数作为回调函数
C++ 友元函数的函数指针
成员函数的指针 讲友元之前先讲普通的成员函数的函数指针 <code class=sourceCode>class Std_interface { public: virtual void suspend() = 0; }; // define the pointer of function typedef void (Std_interface::* Pstd_mem) () void f(Std_interface* p) { Pstd_mem s = &Std_interface::suspend; // call d


