Позвольте мне начать с того, что я понимаю, как работают виртуальные методы (полиморфизм, поздняя привязка, vtables).C++ следует использовать виртуальные методы?
Мой вопрос заключается в том, должен ли я сделать свой метод виртуальным. Я проиллюстрирую свою дилемму по конкретному делу, но любые общие рекомендации также будут приветствоваться.
Контекст:
Я создаю библиотеку. В этой библиотеке у меня есть класс CallStack
, который захватывает стек вызовов и затем предлагает векторный доступ к захваченным кадрам стека. Захват выполняется методом protected
CaptureStack
. Этот метод может быть переопределен в производном классе, если пользователи библиотеки хотят реализовать другой способ захвата стека. Чтобы быть ясным, обсуждение метода virtual
применимо только к некоторым методам, которые, как мне известно, могут быть переопределены в производном классе (в данном случае CaptureStack
и destructor
), а не ко всем методам класса.
В моей библиотеке я использую объекты CallStack
, но никогда не показывался в качестве указателей или контрольных параметров, поэтому virtual
не нужен, учитывая только использование моей библиотеки.
И я не могу придумать случай, когда кто-то захочет использовать CallStack
в качестве указателя или ссылки для реализации полиморфизма. Если кто-то хочет получить CallStack
и переопределить CaptureStack
Я думаю, что просто использовать объект производного класса будет достаточно.
Теперь только потому, что я не могу думать, что полиморфизм понадобится, не следует ли использовать методы virtual
, или я должен использовать virtual
, независимо от того, как метод может быть переопределен.
Пример, как CallStack
может быть использован за пределами моей библиотеки:
if (error) {
CallStack call_stack; // the constructor calls CaptureStack
for (const auto &stack_frame : call_stack) {
cout << stack_frame << endl;
}
}
производного класса, который переопределяет CaptureStack
может быть использование в той же манере, не нуждаясь полиморфизм:
if (error) {
// since this is not a CallStack pointer/reference, virtual would not be needed.
DerivedCallStack d_call_stack;
for (const auto &stack_frame : d_call_stack) {
cout << stack_frame << endl;
}
}
Виртуальные функции являются дорогостоящими (с точки зрения производительности), но вы не всегда можете делать что-то без них. С другой стороны, C++ - это не только язык OOP, но и множество других функций/инструментов для выполнения такого рода вещей (параметрический полиморфизм через шаблоны, разработки на основе политик и т. Д.). Дело в том, что: ** C++ не ограничивается только полиморфизмом времени выполнения, поскольку другие языки OOP высокого уровня, такие как Java. ** Чтобы иметь полиморфное поведение, вам не нужно впадать в виртуальные функции. – Manu343726
Общий намек: если вы не используете специальные шаблоны дизайна, вам, возможно, действительно не нужны виртуальные или чистые виртуальные методы. Framework designera также может использовать их. Я для себя действительно использую только виртуальные или чистые виртуальные методы, когда я проектирую архитектуру программного обеспечения, которая извлекает выгоду из переопределяющих супер методов. В простой разработке приложений я избегаю этого. Надеюсь это немного поможет. – icbytes
@icbytes даже в больших программных архитектурах, виртуальные функции не нужны. Проекты на основе политик/компонентов, а не большие иерархии, основанные на booooom-объектах OOP, возможны, используются и не полагаются на виртуальные методы. – Manu343726