2016-12-02 5 views
3

В приведенном ниже коде на Си ++ с использованием виртуальных функцийВиртуальная функция в C++

#include<iostream> 
using namespace std; 
class Base{ 
    public: 
    virtual void fun(){ 
     cout << "Base::fun()called \n"; 
    } 

}; 

class Child : public Base { 
    public: 
    void fun() { 
     cout << "Child::fun() called\n"; 
    } 

    void door(){ 
     cout << "Child::door() called \n"; 
    } 
}; 


int main(){ 

    Base *base_ptr = new Child(); 
    base_ptr->fun(); 
    return 0; 
} 

Как я вызываю функцию двери с помощью base_ptr? Этот вопрос задавали в интервью. мне было интересно, может ли это быть возможным

Спасибо за ваши ответы

+0

Добавить 'виртуальной дверь недействительной() = 0;' к вам объявлению класса для 'Base'. Или вы не можете изменить базу? – drescherjm

+0

@ drescherjm. Нет, вы не можете изменить Base – Zaks

+0

Вы знаете, возможно, это был всего лишь трюк, чтобы выяснить, как вы реагируете, когда вы видите ООП и классы, которые были так неправильно использованы. –

ответ

6

(Если предположить, что Base и Child не могут быть изменены.)

Вы можете использовать static_cast конвертировать base_ptr в Child*.

static_cast<Child*>(base_ptr)->door() 

Это безопасно, пока вы уверены, чтоbase_ptr на самом деле указывает на Child инстанции.


Если вы не знаете, что полученный тип экземпляра base_ptr указывает на, рассмотреть вопрос об использовании dynamic_cast:

if(auto child = dynamic_cast<Child*>(base_ptr)) 
{ 
    child->door(); 
} 

Если компилятор не удается агрессивно оптимизировать его, dynamic_cast имеет дополнительные накладные расходы во время выполнения по сравнению с static_cast ,

+4

'dynamic_cast' может быть более уместным. –

+1

@FredLarson: нет причин использовать 'dynamic_cast' в этой конкретной ситуации. –

+3

@VittorioRomeo: Вы указали причину в своем ответе, так как 'static_cast' будет действительным,« вы должны быть уверены, что 'base_ptr' фактически указывает на экземпляр« Child' ». 'dynamic_cast' позволяет вам определить, так ли это. –

0

Поскольку Base не имеет метода door(), вы, очевидно, не можете просто позвонить base_ptr->door().

Однако, если вы знаете, base_ptr является Child, вы можете бросить его, а затем вызвать door()

Child* child_ptr = static_cast<Child*>(base_ptr); 
child_ptr->door();