再谈C++类成员函数的指针问题

babysloth babysloth 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
关于C++类成员函数的指针问题,CSDN已经有很多人问过了,举个例子。
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

maoyeahcom

C++指向类成员函数的指针详细解析

由于这几天在开发中要用到函数指针,所以就整理了一下关于函数指针的概念

weixin_38606041

C++ 指向类成员的指针

前面曾写过一篇恼人的函数指针(一),总结了普通函数指针的声明、定义以及调用,还有函数指针数组,函数指针用作返回值等。但是作为C++的研读,我发现我漏掉了一个最重要的内容,就是指向类成员的指针,这里将做相应补充(相关代码测试环境为vs 2010)。 指向类成员的指针总的来讲可以分为两大类四小类(指向数据成员还是成员函数,指向普通成员还是静态成员),下面一一做介绍: 一、指向类的普通成员的指针(非静态) 1、指向类成员函数的指针 简单的讲,指向类成员函数的指针与普通函数指针的区别在于,前者不仅要匹配函数的参数类型和个数以及返回值类型,还要匹配该函数指针所属的类类型。总结一下,比较以下几点: a)参

weixin_38556985

c++类成员函数作为回调函数

c++类成员函数作为回调函数

moisp

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

weixin_38660731
评论 32
收藏 已收藏
分享
返回顶部
babysloth
C语言 70,039 成员 243,237 内容