当前位置:  开发笔记 > 编程语言 > 正文

如何在C++中实现指向成员函数的指针?

如何解决《如何在C++中实现指向成员函数的指针?》经验,为你挑选了1个好方法。

c ++中指向成员函数的指针分为三部分:

Offset
Address/index
virtual?

当使用调用派生对象时,偏移用于指针调整 base pointer.

这个偏移是如何实现的?它是指向某个表的指针,每个派生类有一个表,该表是否包含表单的条目(base X, offset)

另外,我在哪里可以获得更多关于此的信息?



1> 6502..:

首先,您应该注意到C++方法可以实现(并且通常实现),就像常规函数一样,在所有其他参数之前接受额外的隐藏参数this.

换句话说

struct P2d {
   double x, y;
   void doIt(int a, double b) {
       ...
   }
};

机器代码doIt与C编译器生成的机器代码相同

void P2d$vid$doIt(P2d *this, int a, double b) {
    ...
}

p->doIt(10, 3.14)编译的调用P2d$vid$doIt(p, 10, 3.14);

鉴于此,没有虚方法的简单类的方法指针可以实现为方法代码的常规指针(注意:我正在使用vid"Void of Int + Double"作为"名称修改"的玩具示例C++编译器可以处理重载 - 具有相同名称但参数不同的不同函数.

如果该类具有虚拟方法,则不再如此.

大多数C++编译器都实现虚拟调度,而不是VMT ...即

struct P2d {
    ...
    virtual void doIt(int a, double b);
};

调用的代码就像p->doIt(10, 3.14)where pa P2d *是一样,与C编译器生成的代码相同

(p->$VMTab.vid$doIt)(p, 10, 3.14);

即实例包含一个指向虚方法表的隐藏指针,该指针表示每个成员包含有效代码地址(假设编译器无法推断出该类p确实P2d而不是派生类,因为在这种情况下,调用可以与非虚方法).

方法指针需要尊重虚方法...即,doIt使用派生的实例上的方法指针间接调用P2d是调用派生版本所必需的,而相同的方法指针则是在P2d实例上使用时调用基本版本.这意味着选择要调用的代码取决于指针和类实例.

可能的实现是使用蹦床:

void MethodPointerCallerForP2dDoit(P2d *p, int a, double b) {
    p->doIt(a, b);
}

在这种情况下,方法指针仍然只是指向代码的指针(但对于蹦床,而不是最终方法).

另一种方法是将方法的索引存储在VMT内部作为方法指针.这是可行的,因为在C++中,方法指针与特定类相关联,因此编译器知道该类是否存在虚拟方法.

多重继承不会使方法指针复杂化,因为在编译时,所有内容都可以解析为单个最终VMT表.

推荐阅读
手机用户2402851155
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有