Почему я должен избегать множественного наследования в C ++? - PullRequest
157 голосов
/ 02 января 2009

Хорошо ли использовать множественное наследование или я могу вместо этого заняться другими вещами?

Ответы [ 15 ]

1 голос
/ 07 августа 2014

Ключевая проблема с MI конкретных объектов заключается в том, что редко у вас есть объект, который на законных основаниях должен быть «быть A и быть B», поэтому это редко является правильным решением по логическим причинам. Гораздо чаще у вас есть объект C, который подчиняется «C может действовать как A или B», чего вы можете достичь с помощью наследования и компоновки интерфейса. Но не заблуждайтесь - наследование нескольких интерфейсов все еще является MI, только его подмножеством.

В частности, для C ++ основным недостатком функции является не фактическое СУЩЕСТВОВАНИЕ множественного наследования, но некоторые конструкции, которые допускают это, почти всегда имеют дефекты. Например, наследование нескольких копий одного и того же объекта, например:

class B : public A, public A {};

искажен ОПРЕДЕЛЕНИЕМ. В переводе на английский это «B - это A и A». Так что даже в человеческом языке есть серьезная двусмысленность. Вы имели в виду "B имеет 2 As" или просто "B есть A"? Допуская такой патологический код и, что еще хуже, сделав его примером использования, C ++ не оказал никакой пользы, когда дело дошло до того, что он сохранил эту функцию на последующих языках.

1 голос
/ 02 января 2009

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

Композиция по своей сути проста для понимания, понимания и объяснения. Написание кода для него может быть утомительным, но хорошая IDE (прошло несколько лет с тех пор, как я работал с Visual Studio, но, безусловно, во всех IDE Java есть отличные инструменты автоматизации сочетаний клавиш), вы должны преодолеть это препятствие.

Кроме того, с точки зрения обслуживания, «проблема с бриллиантами» возникает и в случаях не буквального наследования. Например, если у вас есть A и B, и ваш класс C расширяет их оба, а у A есть метод 'makeJuice', который делает апельсиновый сок, а вы расширяете его, чтобы сделать апельсиновый сок с оттенком лайма: что происходит, когда дизайнер для ' B 'добавляет метод' makeJuice ', который генерирует электрический ток? «А» и «В» могут быть совместимыми «родителями» прямо сейчас , но это не значит, что они всегда будут такими!

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

1 голос
/ 02 января 2009

Использование и злоупотребление наследованием.

Эта статья прекрасно объясняет наследование и его опасности.

0 голосов
/ 02 января 2009

требуется 4/8 байт на каждый участвующий класс. (По одному указателю на класс).

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

0 голосов
/ 02 января 2009

Вы можете использовать композицию вместо наследования.

Общее ощущение, что композиция лучше, и это очень хорошо обсуждается.

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