C ++:访问虚拟方法(C++: Accessing Virtual Methods)

2019-07-05 01:10发布

我试图使用虚拟方法表来调用由指数函数的一类...假设我们有下面的代码:

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语句和case语句......那么,有没有更好的AA的方法来调用只使用指针(访问的虚函数表为例)或类似的东西的方法呢?

对不起,我的英语太可怕了:S ...并在此先感谢!

编辑:感谢所有的建议! 我要扩大我的问题:

解决此之后我要去创建派生类(例如derived1和衍生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 do_something(unsigned int func_numb)
    {
        delete current
        Base* new = current->next_state(stl);
        current = new;
    }
};

Answer 1:

无论是switch语句:

switch (func_number)
{
    case 1:
        f_1();
        break;
    case 2:
        f_2();
        break;
    case 3:
        f_3();
        break;
}

或者使用函数指针数组。



Answer 2:

有访问虚函数表中没有可移植的方法; 语言规范没有规定如何调度虚拟应实施,所以该表甚至存在,更别说是程序访问没有要求。

有没有显著更好的办法做你想要比你所提到的方法是什么:函数指针的表,或if / switch状态。



Answer 3:

我以为你只是想找到所有可能的方式来解决这个问题。

您可以使用指针的地图(或载体)成员函数,一旦初始化它们(在构造函数或静态)。 这可以模拟虚函数表。

这些线之间的事情:

class Base
{
public:
    Base() {
        functions.insert(std::make_pair(1,&Base::f_1));
        functions.insert(std::make_pair(2,&Base::f_2));
        functions.insert(std::make_pair(3,&Base::f_3));
        }
    virtual ~Base() {}
    virtual Base* call_func(unsigned int func_number)
    {
    return (this->*functions[func_number])();
}
protected:
    std::map<unsigned int, Base*(Base:: *)()const> functions;
virtual Base* f_1() const = 0;
virtual Base* f_2() const = 0;
virtual Base* f_3() const = 0;

};

这应该即使是继承类(我会做的工作call_func非虚,虽然)。 是的,你应该检查,如果该项目确实是在地图(或载体),如果它不是一个nullptr



Answer 4:

注1:它是安全访问你的使用方法映射或比使用虚表指针的switch-case方法的方法。

注2:小型组装零件也VC ++,不知道其他的编译器。

虽然存在一种方法来访问虚拟表函数:

// create our object
X *obj = new X();

// access the vtable pointer
int* vptr = *(int**)obj;

// set the this pointer
__asm
{
  mov ecx, obj
}

// call the first method from the vtable
( (void (*)()) vptr[0] )();

见深解释一下: http://kaisar-haque.blogspot.nl/2008/07/c-accessing-virtual-table.html



文章来源: C++: Accessing Virtual Methods