Во многих ситуациях вопрос даже не спрашивает себя, поскольку иногда наследование предоставляет необходимые функции, которые не могут предоставить шаблоны. Например, когда мне нужно обращаться к различным типам через один базовый тип (полиморфизм), мне нужно использовать наследование.
Однако есть случаи, когда проблема может быть решена как с наследованием, так и с шаблонами.
Возьмем, например, стратегическую модель-параметризацию некоторых частей кода:
Одно решение файлового парсера может выглядеть так:
class FileParser
{
//...
public:
void Parse(ParsingAlgorithm* p);
//...
}
void FileParser::Parse(ParsingAlgorithm* p)
{
m_whatevertypeofvaluesineed = p->Parse(whateverparametersyouneed);
}
где ParsingAlgorithm является абстрактным базовым классом, который предоставляет некоторые базовые методы и должен быть унаследован тем, кто любит реализовывать определенный парсер для класса FileParser.
Однако то же самое можно легко достичь с помощью шаблонов:
template <class Parser>
class FileParser
{
//...
public:
void Parse()
{
m_whatevertypeofvaluesineed = m_parser.Parse(whateverparametersyouneed);
}
private:
Parser m_parser;
//...
}
Существуют ли какие-то общие правила, которые я могу использовать, чтобы решить, использовать шаблоны или наследование? Или я должен просто использовать шаблоны, где это возможно, чтобы избежать чрезмерных затрат времени на такие вещи, как виртуальные функции?