C++ C++;:访问虚拟方法
我正在尝试使用虚拟方法表通过索引在中调用函数 一个班级。。。假设我们有以下代码:C++ C++;:访问虚拟方法,c++,pointers,methods,virtual,vtable,C++,Pointers,Methods,Virtual,Vtable,我正在尝试使用虚拟方法表通过索引在中调用函数 一个班级。。。假设我们有以下代码: 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; vir
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语句实现了这个
案例陈述。。。那么,有没有更好的方法来调用方法呢
只使用指针(例如访问vtable)或类似的东西
对不起,我的英语糟透了。。。提前谢谢你
编辑:
谢谢你的建议!我将扩展我的问题:
解决这个问题后,我将创建派生类(例如derived1和derived2)
使用不同的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
/开关
条件。我想您只是想找到所有可能的方法来解决它
您可以使用指向成员函数的指针的映射(或向量)并初始化它们一次(在构造函数中或静态地)。可以模拟vtable的
在这两条线之间:
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;
类基
{
公众:
Base(){
insert(std::make_pair(1,&Base::f_1));
insert(std::make_pair(2,&Base::f_2));
insert(std::make_pair(3,&Base::f_3));
}
虚拟~Base(){}
虚基*调用函数(无符号整数函数号)
{
返回(this->*函数[func_number])();
}
受保护的:
std::map函数;
虚基*f_1()常数=0;
虚基*f_2()常数=0;
虚基*f_3()常数=0;
})
即使对于继承的类,这也应该起作用(不过,我会将call\u func
设置为非虚拟的)。
是的,您应该检查该项是否真的在映射(或向量)中,以及它是否不是
nullptr
注1:使用方法映射或切换案例方法访问您的方法比使用vtable指针更安全。
注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] )();
请参阅此处的详细说明:
你想让“call_func”成为虚拟的吗?好问题。我同意,感觉应该有一种方法可以使用
func_number
直接索引到我们知道已经存在的指针表中(在所有常见的实现中)。遗憾的是,我认为没有if
或switch
是唯一的选择,因为您需要虚拟调用。@NicholasWilson:问题是它只存在于“所有常见实现”中,而不是所有可能的实现中。语言规范不要求它在那里,因此没有可移植的方式来访问它!所以你最好了解你的目标平台。对不起,当我说案例陈述时,我想说的是切换-statement@gvo:啊,我在你的问题中漏掉了。无论如何,这可能是最好的办法。这里有点异味;如果你给我们一个更高层次的解释,我们可以给你一些更好的想法。好的:(谢谢,我想维基百科把我和他关于使用pseudo-c的虚拟方法表的文章搞混了++