Вызывать виртуальный метод без указания на объект?

#include <iostream>

struct A {
    void init()
    {
        internal_init();
    }
    virtual void internal_init()
    {
        std::cout << "internal of A" << std::endl;
    }
};

struct B: public A {
    void internal_init()
    {
        init();
        std::cout << "internal of B" << std::endl;
    }
};

int main(){
    B instance;
    std::cout << "internal of A" << std::endl;
    instance.internal_init();
    return 0;
}

Сначала программа идет в B::internal_init() как и ожидалось. Затем, чтобы A::init() (Я думаю, так как B происходит от A, а B не имеет каких-либо init()). Что теперь?

какие internal_init() это выберет? так как он идет к B::internal_init()Программа войдет в бесконечный цикл, и я не понимаю почему.

  • Что действительно происходит, когда я звоню internal_init()?
  • почему это вызывает internal_init() "B часть" экземпляра? Это о "виртуальном"? Если так, как получилось? Виртуальные функции имеют место, когда мы используем полиморфизм (который, насколько понимает начинающий, он работает с указателями базового класса, которые указывают на объекты производного класса).

2 ответа

Решение

Поскольку instance это B

instance.internal_init();

Позвоню Bs internal_init(), Затем в internal_init() ты звонишь init();, Теперь функции-члены имеют неявный параметр, который является указателем this.

Поэтому, когда мы звоним A"s init() этот указатель на самом деле B, В init() мы называем internal_init(); используя этот указатель на B, поскольку internal_init() является виртуальным, и у нас есть указатель на B механизм виртуального поиска будет вызывать B"s internal_init(),

Затем этот цикл повторяется снова и в конечном итоге вызывает переполнение сегмента или переполнение стека.

Во -первых struct B наследует все функции struct A потому что struct B: public A, Функция internal_init из A переопределяется в B потому что вы используете одну и ту же сигнатуру функции и ключевое слово virtual в A,

Так что теперь звонки:instance.internal_init(); какие звонки internal_init() из B, который вызывает A::init, который вызывает B::internal_init()и т. д., пока не дается ошибка сегментации. Чтобы предотвратить это (и я думаю, что это то, что вы хотите), вы можете явно вызвать internal_init() из A в B вместо звонка init():

struct B: public A {
    virtual void internal_init()
    {
        A::internal_init();
        std::cout << "internal of B" << std::endl;
    }
};
Другие вопросы по тегам