Collected from here . . .
функции Невиртуальные члены разрешаются статически. То есть функция-член выбирается статически (во время компиляции) на основе типа указателя (или ссылки) на объект.
Напротив, виртуальные функции-члены решаются динамически (во время выполнения). То есть функция-член выбирается динамически (во время выполнения) в зависимости от типа объекта, а не от типа указателя/ссылки на этот объект. Это называется «динамическое связывание». Большинство компиляторов используют некоторый вариант следующего метода: если объект имеет одну или несколько виртуальных функций, компилятор помещает скрытый указатель в объект, называемый «виртуальный указатель» или «v-указатель». «Этот v-указатель указывает на глобальную таблицу, называемую« виртуальная таблица »или« v-таблица ».
Чистая виртуальная функция - это функция, которая должна быть переопределена в производном классе и не нуждается в определении. Виртуальная функция объявляется «чистой», используя синтаксис curious = 0. Например:
class Base {
public:
void f1(); // not virtual
virtual void f2(); // virtual, not pure
virtual void f3() = 0; // pure virtual
};
Base b; // error: pure virtual f3 not overridden
Здесь Base является абстрактным классом (поскольку он имеет чисто виртуальную функцию), так что ни один объект класса Base не может быть создан непосредственно: База (явно) означает, что базовый класс. Например:
class Derived : public Base {
// no f1: fine
// no f2: fine, we inherit Base::f2
void f3();
};
Derived d; // ok: Derived::f3 overrides Base::f3
Пример для виртуальных или Невиртуальных Fenction
#include <iostream>
using namespace std;
class Base {
public:
virtual void NameOf(); // Virtual function.
void InvokingClass(); // Nonvirtual function.
};
// Implement the two functions.
void Base::NameOf() {
cout << "Base::NameOf\n";
}
void Base::InvokingClass() {
cout << "Invoked by Base\n";
}
class Derived : public Base {
public:
void NameOf(); // *Virtual function*.
void InvokingClass(); // *Nonvirtual function.*
};
// Implement the two functions.
void Derived::NameOf() {
cout << "Derived::NameOf\n";
}
void Derived::InvokingClass() {
cout << "Invoked by Derived\n";
}
Главной
int main() {
// Declare an object of type Derived.
Derived aDerived;
// Declare two pointers, one of type Derived * and the other
// of type Base *, and initialize them to point to aDerived.
Derived *pDerived = &aDerived;
Base *pBase = &aDerived;
// Call the functions.
pBase->NameOf(); // Call virtual function.
pBase->InvokingClass(); // Call nonvirtual function.
pDerived->NameOf(); // Call virtual function.
pDerived->InvokingClass(); // Call nonvirtual function.
}
Если я неправильно понял намерение вашего вопроса, и это больше похоже на то, как «компилятор разрешает, какую функцию вызывать для виртуальных функций», затем [читайте здесь] (https://stackoverflow.com/questions/ 3103153/overloaded-virtual-function-call-resolution) – CoryKramer
Вы должны посмотреть FAQ [isocpp.org] (https://isocpp.org/) на [виртуальные функции] (https://isocpp.org/ wiki/faq/virtual-functions # overview-virtual-fns) – NathanOliver
Я написал код намеренно, чтобы уточнить сомнение, в 1) компилятор решит использовать виртуальную таблицу, которую он должен вызвать Foo :: foo, поскольку указатель имеет базовый класс & in 2) компилятор решает статически вызвать Foo :: foo2. Итак, как компилятор дифференцируется в обеих ситуациях, прочитав инструкцию. –