2017-01-12 3 views
1

Этот кодНевиртуальные функции перегружен член

#include <iostream> 

struct A { 
    int one() { 
    std::cout << "oneA" << std::endl; 
    } 
    int devone() { 
    one(); 
    } 
}; 

struct B : A { 
    int one() { 
    std::cout << "oneB" << std::endl; 
    } 
}; 
int main() { 
    B b; 
    b.devone(); 
} 

печатает oneâ

Я не понимаю, почему. Я знаю, что если я использую виртуальные функции , то печатается одинB, но почему бы и нет в приведенных выше примерах кода. Нет указателей или ссылок, почему мне нужно объявить функцию виртуальной?

+0

На самом деле есть указатель. Он просто скрыт от вас. Помните, что все функции-члены имеют указатель 'this'. – NathanOliver

+2

Тип 'this' внутри' A :: devone' - 'A *', поэтому вызывается 'A :: one'. – nwp

ответ

2

Нет указателей или ссылок, почему мне нужно объявить функцию виртуальной?

Вы ошибаетесь, этот код:

int A::devone() { 
    one(); 
} 

равно:

int A::devone() { 
    this->one(); 
} 

поэтому используется указатель, и разрешить надлежащую функцию во время выполнения вы должны использовать virtual функцию.

1

Если вы не объявите one как виртуальный, то у него не будет записи в A s vtable. Если нет записи vtable в A, это означает, что только one, о котором он знает, является ее собственным. Поэтому, когда вы звоните one от A::devone, логически единственная функция это может звонок A::one.

1

Он выводит «oneA», потому что вы вызываете A :: devone(), который в свою очередь вызывает A :: one().
Поскольку A :: one() не является виртуальным, даже если у вас есть экземпляр B, метод Base класса() будет вызван в любом случае.

Если добавить

int devone() { 
    one(); 
    } 

к классу B, метод B :: один() будет называться вместо.

Смежные вопросы