В чем отличие от перезаписи не виртуальной функции и виртуальной? - PullRequest
3 голосов
/ 03 мая 2011

В C ++: чем отличается перезапись невиртуальной функции от перезаписи виртуальной?

Ответы [ 2 ]

8 голосов
/ 03 мая 2011

С virtual:

class Base {
    virtual void Foo() { std::cout << "Foo in Base" << std::endl;}
};

class Derived : public Base {
    virtual void Foo() { std::cout << "Foo in Derived" << std::endl;}
};

// in main()
Derived* d = new Derived();
d->Foo(); // prints "Foo in Derived"

Base* b = new Derived();
b->Foo(); // prints "Foo in Derived"

и без (тот же код, но пропустите virtual):

// in main() 
Derived* d = new Derived();
d->Foo(); // prints "Foo in Derived"

Base* b = new Derived();
b->Foo(); // prints "Foo in Base"

так что разница в том, что без virtual нет истинного полиморфизма времени выполнения: какая функция вызывается, определяется компилятором в зависимости от текущего типа указателя / ссылки, через которую она вызывается.

С помощью virtual объекты поддерживают список виртуальных функций (vtable), в котором он ищет фактический адрес вызываемой функции - во время выполнения, каждый раз, когда вы вызываете виртуальный член этой функции. В этом примере запись для Foo неявно модифицируется конструктором Derived, чтобы указывать на переопределенную функцию, поэтому не имеет значения, что Foo вызывается через Base -точку.

0 голосов
/ 03 мая 2011

Перезапись виртуальной функции обеспечит оценку типа объекта во время выполнения и вызов соответствующего метода.

Пример:

class Vehicle
{
public:
   void PrintType(); // Prints "Vehicle"
};

class Car: public Vehicle
{
 // overwrite PrintType to print "Car"
};


// In main
void main()
{
Vehicle *s = new Car();
s->PrintType();  // Prints "Vehicle"

// If PrintType was virtual then the type of s will be evaluated at runtime and the inherited function will be called printing "Car"
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...