Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用vptr调用虚函数 我最近在C++中阅读了虚拟函数和继承,最后用VPTR和VTABLE来完成。p>_C++_Polymorphism_Virtual - Fatal编程技术网

用vptr调用虚函数 我最近在C++中阅读了虚拟函数和继承,最后用VPTR和VTABLE来完成。p>

用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

我的问题与使用vprt调用派生对象的方法有关

我解释一下,下面是我的代码:

    #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:许多编译器将虚拟表指针作为对象的最后一个成员;其他编译器将其作为第一个成员,如果您认为需要关心这些内容的内部,则停止。您这样做是错误的。但了解如何处理这些内容可能会很有用实施“在引擎盖下”,作为语言的用户,您不需要知道也不需要关心。