我试图使用虚拟方法表来调用由指数函数的一类...假设我们有下面的代码:
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;
}
};
无论是switch语句:
switch (func_number)
{
case 1:
f_1();
break;
case 2:
f_2();
break;
case 3:
f_3();
break;
}
或者使用函数指针数组。
有访问虚函数表中没有可移植的方法; 语言规范没有规定如何调度虚拟应实施,所以该表甚至存在,更别说是程序访问没有要求。
有没有显著更好的办法做你想要比你所提到的方法是什么:函数指针的表,或if
/ switch
状态。
我以为你只是想找到所有可能的方式来解决这个问题。
您可以使用指针的地图(或载体)成员函数,一旦初始化它们(在构造函数或静态)。 这可以模拟虚函数表。
这些线之间的事情:
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
。
注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