Когда вы предпочитаете виртуальные функции шаблонам в C ++? - PullRequest
2 голосов
/ 21 февраля 2020

Финансовая компания дала мне интервью, и мне был задан следующий вопрос:
«Перечислите случаи, когда вы предпочитаете виртуальные функции шаблонам?»

Звучит странно для меня, потому что обычно мы стремимся к противоположному праву?
Все книги, статьи, доклады побуждают нас использовать stati c полиморфизм вместо динам c.

Есть ли какие-либо известные случаи, когда я не знал, когда следует использовать виртуальные функции и избегать шаблонов?

Ответы [ 3 ]

2 голосов
/ 21 февраля 2020

GUI / наборы инструментов для визуализации - очевидный случай. Например, повторная реализация метода draw, безусловно, менее трудоемка с виртуальными методами и динамической диспетчеризацией c. А поскольку современный C ++ имеет тенденцию препятствовать управлению необработанными указателями, std::unique_ptr может управлять ресурсом для вас.

Я уверен, что есть множество других иерархических примеров, которые вы можете привести. .. базовый enemy класс для игры с виртуальными методами, обрабатывающими поведение различных злодеев:)

Весь аргумент «накладные расходы» для динамической c отправки сегодня совершенно не заслуживает внимания. Я бы поспорил, что реализация виртуальной косвенной адресации не была серьезной нагрузкой для серьезных нагрузок в течение десятилетий. Есть более интересный вопрос, что если бы C ++ был разработан сегодня, был бы полиморфизм частью языка? Но это ни здесь, ни там сейчас.


Мне не нравятся шансы этот вопрос остается открытым, так как это не является прямой проблемой программирования и, вероятно, слишком подвержен мнениям. Это может быть лучшим вопросом для разработки программного обеспечения .

2 голосов
/ 21 февраля 2020

Когда тип объекта неизвестен во время компиляции, используйте virtual методы.

например,

void Accept (Fruit* pFruit)  // supplied from external factors at runtime
{
  pFruit->eat();   // `Fruit` can be anyone among `Apple/Blackberry/Chickoo/`...
}

В зависимости от того, что пользователь вводит, фрукт будет поставлен на функцию. Следовательно, мы никак не можем понять, что будет eat(). Поэтому он является кандидатом на полиморфизм во время выполнения:

class Fruit
{
  public: virtual void eat () = 0;
}

Во всех остальных случаях всегда предпочитайте полиморфизм stati c (включая template s). Это более детерминистично c и прост в обслуживании.

0 голосов
/ 21 февраля 2020

Кажется, что вопрос об интервью спрашивает о предпочтениях (и ваших соображениях). Я бы предпочел интерфейсы (виртуальные методы) для простоты создания макетов для модульного тестирования. Мы можем использовать шаблон для них, но это громоздко (потребитель должен быть шаблонным). Если профилирование не приводит к снижению скорости при поиске в vtable, предпочтительнее, чем пересмешивать / тестировать не виртуальные методы.

Кроме того, введите стирание. Я не думаю, что это может быть реализовано вообще с использованием шаблонов. Стирание типа можно условно представить как void ptr и указатели на функции, которые можно легко реализовать с помощью интерфейсов + виртуальных методов.

Для шаблонов требуется реализация кода, чтобы быть доступными. Я полагаю, что виртуальные методы интерфейса могут быть вызваны на дочернем ptr только с его двоичным (объектным) файлом.

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

...