调用虚拟方法的不同方法

时间:2012-12-12 14:41:03

标签: c++ class methods virtual

  

可能重复:
  C++: Accessing Virtual Methods

我正在尝试使用虚方法表来通过索引来调用函数 一类......假设我们有以下代码:

class Base
{
public:
    Base() {}
    virtual ~Base() {}

    virtual Base* call_func(unsigned int func_number)
    {
       // Some way to call f_n
    }
protected:
    virtual Base* f_1() const = 0;
    virtual Base* f_2() const = 0;
    virtual Base* f_3() const = 0;
};

我已经使用函数数组if-statement实现了这个 和case-statement ...所以,有没有一种更好的方法来调用方法 仅使用指针(例如访问vtable)或类似的东西?

解决此问题后,我将创建派生类(例如derived1和derived 2) 使用f_1,f_2,f_3的不同实现,并具有如下类控件:

class Control
{
protected:
    Base* current;

public:
    Control(Base* curr = new derived1): current(curr) {}
    virtual ~Control() 
    {
        delete current;
    }
    virtual void call_functions(unsigned int func_numb)
    {
        delete current
        Base* new = current->call_func(func_numb);
        current = new;
    }
};

对不起我可怕的英语:S ...并提前致谢!

3 个答案:

答案 0 :(得分:1)

C ++没有很好的内置内省,也就是说,你可能知道,你不能在运行时按名称查找成员函数,并从命名查找中调用它。但是你可以创建一个成员函数指针表;例如,请参阅C ++ FAQ Lite条目How do I create and use an array of pointer-to-member-function?中的示例。 (我希望这与你已经提到过的“功能阵列”不一样,但它似乎是实现你想要的最佳方式。)

如果我可能会问,你为什么需要按索引调用函数?通常存在虚函数来使用它们自己的任务参数来完成特定任务。

如果你更直接地访问vtable,你可能会做一些工作,但它会很脆弱且不便携。

答案 1 :(得分:0)

使用指向成员函数的指针:

virtual Base* call_func(Base *(Base::*pf)())
{
  return this->*pf();
}

如果您需要将参数作为算术标量,请使用查找数组:

virtual Base* call_func(unsigned int func_number)
{
  static const Base *(Base::*(table[]))() = { &Base::f_1, &Base::f_2, &Base::f_3 };
  return this->*(table[func_number])();
}

答案 2 :(得分:0)

只是一个粗略的代码。

void *vptr = *(void**)this;
void *method = ((void**)vptr)[index + first_method_offset];
typedef void (*method_type)();
void *m = (method_type)method;
m();

如果索引方法不是vtable中的第一个,则需要first_method_offset。