用vptr调用虚函数 我最近在C++中阅读了虚拟函数和继承,最后用VPTR和VTABLE来完成。p>
我的问题与使用vprt调用派生对象的方法有关 我解释一下,下面是我的代码:用vptr调用虚函数 我最近在C++中阅读了虚拟函数和继承,最后用VPTR和VTABLE来完成。p>,c++,polymorphism,virtual,C++,Polymorphism,Virtual,我的问题与使用vprt调用派生对象的方法有关 我解释一下,下面是我的代码: #include <iostream> using namespace std; class base { public: void fun_1() { cout << "base-1\n"; } virtual void fun_2() { cout << "base-2\n"; } virt
#include <iostream>
using namespace std;
class base
{
public:
void fun_1() { cout << "base-1\n"; }
virtual void fun_2() { cout << "base-2\n"; }
virtual void fun_3() { cout << "base-3\n"; }
virtual void fun_4() { cout << "base-4\n"; }
};
class derived : public base
{
public:
void fun_1() { cout << "derived-1\n"; }
void fun_2() { cout << "derived-2\n"; }
void fun_4() { cout << "derived-4\n"; }
};
int main()
{
base *p;
derived obj1;
p = &obj1;
void(*firstfunc)() = (void(*)(void))(*(int*)*(int*)p);
firstfunc();
}
#包括
使用名称空间std;
阶级基础
{
公众:
void fun_1(){cout
如何调用第二个函数
你可以这样称呼它:
p->fun_2();
印刷品:
derived-2
虚拟表和虚拟函数指针是编译器的实现细节。一般来说,您不应该关心这些实现细节,因为如果您编写不可移植的代码。实际上,我甚至不确定您的代码是否有未定义的行为,如果有,甚至连将vpointer放置在pl上的编译器都不知道你所期望的ace可以打印垃圾。无论如何,不要这样做,除非你需要,这实际上是永远不会的;)
作为旁注,如果使用别名,函数指针会失去很多恐惧感,例如
using base_mem_fun = void (base::*)();
base_mem_fun first_base = &base::fun_1;
(p->*first_base)();
印刷品:
base-1
你是从哪里想到要写void(*firstfunc)(=(void(*)(void))(*(int*)*(int*)*(int*)p)
的?Vtables和vptr是内部实现细节,这段代码取决于未定义的行为。不需要(实际上也没有保证的支持)访问任何vtable
;只需执行p->fun_1()
或p->fun_2()
;然后该语言为您处理动态绑定。@该页中的Blood HaZaRd:许多编译器将虚拟表指针作为对象的最后一个成员;其他编译器将其作为第一个成员,如果您认为需要关心这些内容的内部,则停止。您这样做是错误的。但了解如何处理这些内容可能会很有用实施“在引擎盖下”,作为语言的用户,您不需要知道也不需要关心。