В ОО-программировании, каковы некоторые негативные последствия наследования? - PullRequest
3 голосов
/ 20 октября 2011

Я знаю, что есть некоторые положительные аспекты наследования, но я не знаю отрицательных последствий наследования во время выполнения?Кто-нибудь может сказать мне об этом, спасибо!

Ответы [ 8 ]

4 голосов
/ 20 октября 2011
  • Большие системы, основанные на наследовании, обычно используют больше памяти и имеют худшее расположение данных, чем системы, основанные на композиции, это требует затрат времени выполнения с точки зрения скорости из-за поведения кеша (вы хотите, чтобы все связанное было так плотно упаковановозможно).
  • Для вызова виртуальных функций требуется обращение к таблице виртуальных функций, чтобы получить правильную функцию для вызова, это может быть дорогостоящим из-за поведения кэша, виртуальная таблица может быть далека от вызывающей функции.
  • Множественное наследование еще больше увеличивает стоимость вызовов виртуальных функций, так как сначала может потребоваться вычисление смещения для получения правильного vtable.
  • Если вы используете RTTI, то выобычно видят дополнительные данные в фиксированном месте по отношению к vtable.Это влияет на локальность vtable, которая снова запрещает кеш.
3 голосов
/ 20 октября 2011

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

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

Обновление :Я рассмотрел влияние наследования на производительность здесь.Другие ответы могут сказать больше о правильности ОО.

1 голос
/ 21 октября 2011

После прочтения других (информативных!) Ответов, я считаю, что одно потенциальное негативное влияние еще не было упомянуто:

Наследование часто используется для достижения полиморфии. В C ++ это означает, что вы передаете ссылки (ссылки или указатели C ++) в базовый тип вместо того, чтобы передавать его по значению, чтобы избежать проблемы sling . На практике передача ссылок вокруг часто означает, что область объекта больше не должна определять его время жизни, поэтому люди начинают использовать динамическое управление памятью (скажем, new и delete). И этот может открыть целую банку с червями.

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

1 голос
/ 21 октября 2011

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

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

1 голос
/ 20 октября 2011

Преимущества использования наследования значительно перевешивают недостатки.

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

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

Не виртуальные вызовы функций стоят одинаково с точки зрения производительности.

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

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

1 голос
/ 20 октября 2011

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

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

Как правило, накладные расходы на объектно-ориентированное программирование достаточно малы, и вам нужно думать об этом только при обработке больших объемов данных. Посмотрите презентацию от Sony об объектно-ориентированном программировании - она ​​рассматривает производительность ООП с точки зрения разработчика игры.

1 голос
/ 20 октября 2011

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

0 голосов
/ 20 октября 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...