вызов виртуальной функции по vptr - PullRequest
0 голосов
/ 30 мая 2018

Недавно я читал о виртуальных функциях и наследовании в C ++, и в результате я получил vptr и VTABLE.

Мой вопрос связан с вызовом методов производных объектов средствами 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();
    }

результат:

производная-2

Хорошо,до сих пор, операции, сделанные с (void(*)(void))(*(int*)*(int*)p) все еще нечеткими в моей голове, но как я могу сделать, чтобы вызвать вторую функцию?

Thx

1 Ответ

0 голосов
/ 31 мая 2018

как я могу сделать, чтобы вызвать вторую функцию?

Вы бы назвали это так:

p->fun_2();

печатает:

derived-2

Виртуальные таблицы и указатели виртуальных функций - это детали реализации вашего компилятора.В общем, вам не следует заботиться о таких деталях реализации, потому что если вы пишете непереносимый код.На самом деле, я даже не уверен, имеет ли ваш код неопределенное поведение или нет, даже если это так, даже компилятор, который размещает vpointer в том месте, где вы ожидаете, может напечатать мусор.Во всяком случае, не делайте этого, если вам не нужно, что на самом деле никогда;).

Как указатель функции, указатели на функции теряют много своей шершавости, если вы используете псевдонимы, например

using base_mem_fun = void (base::*)();
base_mem_fun first_base = &base::fun_1;
(p->*first_base)();

отпечатки:

base-1
...