2012-05-23 2 views
2

Интересно, что то, что я сейчас делаю, является позором для C++, или если все в порядке.C++: наследование без виртуальности

Я работаю над кодом для вычислительного назначения. Для некоторых классов я использую обычную схему наследования с виртуальностью/полиморфизмом. Но мне нужны некоторые классы для интенсивного вычисления, и было бы здорово избежать накладных расходов из-за виртуальности.

В принципе, я хочу использовать эти классы без указателей или перенаправления: наследование только здесь, чтобы избежать много копий/вставки кода (размер файла базового класса равен 60Ko (что много кода)). Таким образом, нет виртуальных функций и нет виртуального дескриптора.

Интересно, отлично ли это с точки зрения C++ или может создавать побочные эффекты (соответствующие классы будут много использоваться в программе).

спасибо.

+5

Это нормально, но виртуальные методы на самом деле не имеют больших накладных расходов. Если ваше «интенсивное вычисление» не включает в себя нелепое количество вызовов виртуальных методов, то это действительно не имеет значения. – robert

+5

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

+1

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

ответ

3

Не использовать virtual членов/наследование в порядке. C++ предназначен для того, чтобы развлекать обширную аудиторию, и это никому не ограничивает конкретную парадигму.

Вы можете использовать C++ для кодирования процедурных, общих, объектно-ориентированных или любых комбинаций из них. Просто постарайтесь сделать все возможное.

В настоящее время я делаю это позор для C++, или если все в порядке.

Совсем нет.
Скорее, если вам не нужен дизайн OO и все еще навязывающий его только ради этого, было бы позором.

В принципе, я хочу, чтобы использовать эти классы без указателей или перенаправления ...

На самом деле вы собираетесь в правильном направлении. Использование указателей, массивов и таких низкоуровневых функций лучше подходит для предварительного программирования. Вместо этого используйте std::shared_ptr, std::vector и стандартные библиотеки.

+1

Я не думаю, что он означает * виртуальное наследование *, а скорее использование или отсутствие * функций виртуального * члена в дереве наследования. Точно так же, когда он говорит * без указателей или перенаправления, я считаю, что он означает только * auto * выделенные объекты. –

+0

@ DavidRodríguez-dribeas, исправил первую часть. Также в некотором смысле контейнеры, такие как 'shared_ptr/vector', также являются автоматически выделенными объектами. – iammilind

+0

'shared_ptr' выделяется в стеке, но фактический заостренный объект отсутствует. То же самое касается вектора, векторный объект находится в стеке, память находится в куче –

5

Использование полиморфизма в C++ не является ни хорошим, ни плохим. Полиморфизм служит цели, равно как и отсутствие полиморфизма. Нет ничего плохого в использовании наследования без использования полиморфизма.

Поскольку полиморфизм служит цели, а недостаток полиморфизма также служит цели, вы должны проектировать свои классы с учетом этих целей. Если, например, вам требуется привязка времени выполнения к экземплярам класса, вам нужен полиморфизм.

Что все сказано, есть правильные и неправильные причины выбора одного подхода над другим. Если вы разрабатываете свои классы без полиморфизма строго, потому что вы хотите «избежать накладных расходов», это, вероятно, неправильная причина. Это пример преждевременной оптимизации, если вы делаете изменения дизайна или решения без профилирования кода и доказали, что полиморфизм является реальной проблемой.

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

1

В основном, вы являетесь , используя наследование без полиморфизма. И все в порядке.

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

3

Я бы перефразировать вопрос:

Что наследство приносит, что композиция не может достичь, если вы избегаете полиморфизм?

Если ответ ничего, что я подозреваю, то, возможно, это наследование не требуется в первую очередь.

+1

+1 Я думаю, что ваши подозрения могут быть правильными. Если цель состоит в том, чтобы предотвратить код обрезания, состав должен быть предпочтительным во многих случаях. – daramarak

1

В общем, это не рекомендуется использовать наследование для повторного использования кода. Наследование скорее должно быть используется кодом, который был разработан для использования вашего базового класса. Я бы предложил другой подход к проблеме. Рассмотрим некоторые альтернативы, такие как композиция, изменение функциональности, которая будет реализована в бесплатных функциях, а не в базовом классе, или статический полиморфизм (с использованием шаблонов).

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