2013-03-13 8 views
0

Правильно ли вызывать виртуальную функцию базового класса, реализованного в производном классе, в не виртуальной функции базового класса. Что-то вродеВызов виртуальной функции базового класса в не виртуальной функции базового класса

class A 
{ 
virtual void func1() = 0; 

void func2() 
{ 
    func1(); 
} 
}; 

class B : public A 
{ 
virtual void func1() 
{ 
    //do something here; 
} 
}; 

int main() 
{ 
A* obj = new B; 
obj->func2(); 
return 0; 
} 

ответ

1

Да. Этот метод используется, когда вам нужно поведение виртуальных функций для реализации операторов: вы определяете свой оператор в терминах виртуальной (или абстрактной) функции и позволяете специализациям решать, как эта функция реализована.

пример:

class base 
{ 
// yada yada yada 
    base& operator=(const base& other) { return assign(other); } 
protected: 
    virtual base& assign(const base& other) = 0; // specializations will decide 
               // what assignment means 
}; 

Edit: одно использования метода является возможность специализации вашего класса контролировать только часть более сложной операцию:

class database 
{ 
public: 
    void execute(const std::string& query) 
    { 
     begin_transaction(); // in practice, this should be RAII 
     connection_.execute(query); 
     end_transaction(); 
    } 
protected: 
    virtual void begin_transaction() = 0; 
    virtual void end_transaction() = 0; 
private: 
    whatever &connection_; 
}; 

В специализациях базы данных, гипотетический mysql_database::begin_transaction имел бы другую реализацию, чем sqlite_database::begin_transaction.

2

Да, это сработает. Вы сами это пробовали?

+2

+1. Конечно, иногда «попробуйте» приводит к таким вещам, как «y = x ++ + x ++» - что «работает», но не «работает правильно каждый раз». Так что только потому, что что-то работает, это не значит, что это приемлемо или даже правильно. –

1

Да, это нормально. Это позволяет обеспечить общий поток в базовом классе, детали которого специализируются на его дочерних элементах.

См. template method.

+0

ОК, спасибо :). Я пытался что-то сложное в func1, которое давало мне ошибки компоновщика, которые, по моему мнению, были связаны с ошибкой реализации :) – raveesh

2

Не только это хорошо известный и эффективный способ решения задач, но если func2 встроен, это, вероятно, означает, что нет лишних накладных расходов по сравнению с прямым вызовом внутренней функции. Очевидно, что иногда вся цель состоит в том, чтобы сделать некоторые вещи внутри func1, а затем вызвать func2 в середине или в конце, но в тех случаях, когда эта дополнительная работа минимальна, «дополнительный функциональный слой», вероятно, полностью исчезает.

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