"У чистой виртуальной (pure virtual function) функции отсутствует реализация"
"тело определено как 0"
Вообщем, начинающий программист читает подобные вещи и запоминает: "Ну всё, значит у чистой виртуальной функции реализации (тела) быть не может". А это в корне неправильно. Реализация может быть. Приведу простой пример:
#include <iostream> class ISomeInterface { public: virtual void someMethod() const = 0; }; void ISomeInterface::someMethod() const { std::cout << "Default implementation of someMethod" << std::endl; } class SomeClass : public ISomeInterface { public: void someMethod() const; }; void SomeClass::someMethod() const { ISomeInterface::someMethod(); std::cout << "SomeClass implementation of someMethod" << std::endl; } int main( int argc, char* argv[] ) { SomeClass obj; obj.someMethod(); return 0; }Результатом выполнения данного кода будет:
Default implementation of someMethod SomeClass implementation of someMethodНикаких ошибок, предупреждений (я использую gcc 4.6.1 с флагом -Wall) не было. Всё корректно скомпировалось и выполнилось. Во-первых, стоит отметить, что реализация данной функции должна быть определена вне класса, как примере. Вот так не получится:
... class ISomeInterface { public: virtual void someMethod() const = 0 { std::cout << "Default implementation of someMethod" << std::endl; } }; ...компилятор выдаст ошибку:
error: pure-specifier on function-definitionИ второе, это то, что данная реализация чистой виртуальной функции может быть использована в производных классах только явно:
... ISomeInterface::someMethod(); ...Данный пост направлен, в первую очередь на то, чтобы начиющие программисты, после таго как они уже станут чуть взрослее (в профессиональном плане) не удивлялись такой ситуации. Или еще хуже, можно ляпнуть такое на собеседовании в серьёзной компании, тем самым вызвать у работодателя мысль, что вы не читали сёрьёзных книг по C++, описывающих эту ситуацию. Тут возникает другой вопрос. А нужно ли это? Когда вообще это применять? И правильно ли это делать? Например, один из гуру C++ Scott Meyers в своей замечательной книге Effective C++, пишет по этому вопросу следущее:
"Кроме песпективы блеснуть перед друзьями-программистами во время вечеринки, знание это особенности вряд ли даст вам что-то значительное". Но дальше всё-таки он приводит примеры применения (правило 36). Я немного скомпоную его мысли, свои взгляды и то, что еще прочитал и пообщался по этой теме.
В реализации данной функции может быть заложено некоторое поведение по-умолчанию или стандартное поведение (как это сделано в обычных виртуальных функциях), но делая её чистой, мы как бы говорим тем, кто будет наследовать этот абстрактный базовый класс, что обязательно нужно переопределить в своём классе и написать реализацию данной функции. А вот использовать эту реализацию по умолчанию или написать свою - это уже на ваше усмотрение.
Может возникнуть такая ситуация, что вообще желательно объявить функцию просто виртуальной (в базовом классе) и указать её реализаю, которая будет использоваться в 95% случаев. Но в 5% случаев, нужно будет определить какую-то особую, специфичную реализацию. Как раз тот факт, что функция чистая виртуальная заставляет нас переопределять её во всех производных классах, и мы точно не забудем это сделать для 5% случаев (это делается, так сказать в целях безопасности). Но при этом мы можем использовать реализацию по умолчанию (из базового класса) для 95% случаев.
Есть и обратная сторона медали, о которой поведал один мой знакомый, авторитетный для меня C++ разработчик - что это выглядит очень неинтуитивно. Когда программист видит чистый виртуальный метод в заголовочном файле, означает, что он пуст и его нельзя вызвать. Я в принципе согласен с этим недостатком. От себя добавлю, что если касаться, например самодокументируемости кода (к чему как правило надо стремиться), то это накладывает определённые противоречения, особенно, если такая штука заложена в какой-то библиотеке.
Как итог, хочу сказать следующее. Да, это по сути некий хак, возможножно упущение или дыра в стандарте, не мне судить, но знать про это надо и знать что такое может быть необходимо. А вот применять или нет - это уже на ваше усмотрение.