Это происходит, когда вы пытаетесь получить доступ к элементу массива с синтаксисом с квадратной скобкой, но вы делаете это по строке, а не по массиву, поэтому операция явно не имеет смысла .
Пример:
$var = "test";
echo $var["a_key"];
Если вы считаете, что переменная должна быть массивом, см., где она появляется и исправить там проблему.
Множественное наследование (сокращенный как MI) запахи , что означает, что обычно , это было сделано по плохим причинам, и будет дуть ветер назад перед лицом специалиста по обслуживанию.
Это верно для наследования, и таким образом, это еще более верно для множественного наследования.
Делает Ваш объект, действительно должен наследоваться от другого? Car
не должен наследоваться Engine
для работы, ни Wheel
. Car
имеет Engine
и четыре Wheel
.
при использовании множественного наследования для разрешения этих проблем вместо состава, тогда Вы сделали что-то не так.
Обычно, у Вас есть класс A
, тогда B
, и C
оба наследовались от A
. И (не спрашивают меня, почему) кто-то тогда решает, что D
должен наследоваться и от [1 111] и C
.
я встретился с этим видом проблемы дважды за 8 лет восьмерок, и забавно видеть из-за:
D
не должен был наследоваться и от [1 114] и от C
), потому что это было плохой архитектурой (на самом деле, C
не должен был существовать вообще...) A
присутствовал дважды в его классе D
внука, и таким образом, обновляя одно родительское поле A::field
, предназначенное, любое обновление его дважды (до [1 120] и C::field
), или наличие чего-то идет тихо неправильно и катастрофический отказ, позже (новый указатель в [1 122], и удалите C::field
...) Используя ключевое слово, виртуальное в C++ для квалификации наследования, избегает двойного расположения, описанного выше, если это не то, что Вы хотите, но так или иначе, по моему опыту, Вы, вероятно, делаете что-то не так...
В Иерархии объектов, необходимо попытаться сохранить иерархию как Дерево (узел имеет ОДНОГО родителя), не как график.
[еще 1161] о Ромбе (редактируют 03.05.2017)настоящей проблеме с Ромбом Страха в C++ ( принятие дизайна является звуковым - рассмотрели Ваш код! ), то, что необходимо сделать выбор :
A
для существования дважды в расположении, и что это означает? Если да, то любой ценой наследовались ему дважды. Этот выбор свойственен к проблеме, и в C++, в отличие от других языков, можно на самом деле сделать это без догмы, вызывающей дизайн на уровне языка.
, Но как все полномочия, с тем питанием прибывает ответственность: Рассмотрите Ваш дизайн.
Множественное наследование нуля или реальных классов, и нуля или большего количества интерфейсов обычно Хорошо, потому что Вы не встретитесь с Ромбом Страха, описанного выше. На самом деле это - то, как вещи сделаны в Java.
Обычно, то, что Вы имеете в виду, когда C наследовался от [1 125] и B
, - то, что пользователи могут использовать C
, как будто это было A
, и/или как будто это было B
.
В C++, интерфейс является абстрактным классом, который имеет:
, Множественное наследование нуля к одному реальному объекту, и нуля или большего количества интерфейсов не считают "вонючим" (по крайней мере, не так).
[еще 1162] об Интерфейсе Краткого обзора C++ (редактируют 03.05.2017)Первый, шаблон NVI может использоваться для создания интерфейса, потому что реальные критерии не должны иметь никакого состояния (т.е. никакие членские переменные, кроме [1 130]). Точка Вашего абстрактного интерфейса должна опубликовать контракт ("можно назвать меня этим путем и этим путем"), ничто больше, ничто меньше. Ограничение наличия только абстрактного виртуального метода должно быть проектным решением, не обязательством.
11103-секундный, в C++, имеет смысл наследоваться фактически абстрактным интерфейсам, (даже с дополнительной стоимостью/косвенностью). Если Вы не сделаете, и интерфейсное наследование появляется несколько время в Вашей иерархии, то у Вас будут неоднозначности.
В-третьих, объектная ориентация является большой, но это не Единственная Истина Там <глоток> ТМ глоток> в C++. Используйте правильные инструменты, и всегда помните, что у Вас есть другие парадигмы в C++, предлагающем другой вид решений.
Иногда, да.
Обычно, Ваш C
класс наследовался от [1 132] и B
, и A
, и B
два несвязанных объекта (т.е. не в той же иерархии, ничем общем, различных понятиях, и т.д.).
, Например, у Вас могла быть система [1 136] с X, Y, Z координаты, которые в состоянии сделать, много геометрических вычислений (возможно, точка, часть геометрических объектов) и каждый Узел является Автоматизированным Агентом, который в состоянии связываться с другими агентами.
, Возможно, у Вас уже есть доступ к двум библиотекам, каждому с его собственным пространством имен (другая причина использовать пространства имен... Но Вы используете пространства имен, не так ли?), один являющийся geo
и другой являющийся ai
, Таким образом, у Вас есть свое собственное own::Node
, происходят и от [1 140] и geo::Point
.
Это - момент, когда необходимо спросить себя, если Вы не должны использовать состав вместо этого. Если own::Node
будет действительно действительно и ai::Agent
и geo::Point
, то состав не сделает.
Тогда Вам будет нужно множественное наследование, имение Вашего own::Node
связывается с другими агентами согласно их положению в 3D пространстве.
(Вы отметите, что ai::Agent
и geo::Point
полностью, полностью, ПОЛНОСТЬЮ НЕ СВЯЗАНЫ... Это решительно уменьшает опасность множественного наследования)
существуют другие случаи:
Иногда можно использовать состав, и иногда MI лучше. Точка: у Вас есть выбор. Сделайте это ответственно (и рассмотрите Ваш код).
Большую часть времени, по моему опыту, нет. MI не является правильным инструментом, даже если это, кажется, работает, потому что это может использоваться ленивым для укладки функций вместе, не осознавая последствий (как создание Car
и Engine
и Wheel
).
, Но иногда, да. И в то время, ничто не будет работать лучше, чем MI.
, Но потому что MI является вонючим, быть готовым защитить Вашу архитектуру в обзорах кода (и защита хорошо, потому что, если Вы не в состоянии защитить его, тогда Вы не должны делать этого).
требуется включенного 4/8 байта за класс. (Один этот указатель в классе).
Это никогда не могло бы быть беспокойством, но если однажды у Вас есть микро структура данных, которая является инстанцированными миллиардами времени, которым это будет.
Можно использовать состав в предпочтении к наследованию.
общее настроение - то, что состав лучше, и он очень хорошо обсужден.
Вне схемы размещения алмазов множественное наследование имеет тенденцию делать объектную модель тяжелее для понимания, который в свою очередь увеличивает затраты на обслуживание.
Состав внутренне легко понять, постигать, и объяснить. Это может стать утомительным для записи кода для, но хороший IDE (это были несколько лет, с тех пор как я работал с Visual Studio, но конечно IDE Java у всех есть большие инструменты автоматизации ярлыка состава) должен получить Вас по тому препятствию.
кроме того, с точки зрения обслуживания, "ромбовидная проблема" подходит в нелитеральных экземплярах наследования также. Например, если у Вас есть A и B, и Ваш класс C расширяет их обоих, и A имеет 'makeJuice' метод, который делает апельсиновый сок, и Вы расширяете это для создания апельсинового сока со скручиванием извести: что происходит, когда разработчик для 'B' добавляет 'makeJuice' метод, который генерирует и электрический ток? И 'B' могут быть совместимые "родители" прямо сейчас , но это не означает, что они всегда будут так!
В целом, принцип того, чтобы иметь тенденцию избежать наследования и особенно множественного наследования, является звуковым. Как все принципы, существуют исключения, но необходимо удостовериться, что существует высвечивающаяся зеленая неоновая вывеска, указывающая на любые исключения, Вы кодируете (и обучаете мозг так, чтобы любое время, Вы видите такие деревья наследования, которые Вы тянете в своей собственной высвечивающейся зеленой неоновой вывеске), и что Вы проверяете, чтобы удостовериться, что все это имеет смысл время от времени.
Использование и Злоупотребления Наследованием.
статья делает отличную работу по объяснению наследования, и это - опасности.
Необходимо использовать его тщательно, существуют некоторые случаи, как Ромбовидная проблема , когда дела могут идти сложные.
(источник: learncpp.com )
Вы не должны "избегать" множественного наследования, но необходимо знать о проблемах, которые могут возникнуть, такие как 'ромбовидная проблема' ( http://en.wikipedia.org/wiki/Diamond_problem ) и рассматривать питание, данное Вам с осторожностью, как Вы должны со всеми полномочиями.
Общедоступное наследование является отношениями ISA, и иногда класс будет типом нескольких различных классов, и иногда важно отразить это.
"Mixins" также иногда полезны. Они - вообще маленькие классы, обычно не наследовавшиеся ничему, обеспечивая полезную функциональность.
, пока иерархия наследования довольно мелка (как это должно почти всегда быть), и хорошо управляемый, Вы вряд ли получите страшное ромбовидное наследование. Ромб не является проблемой со всеми языками, которые используют множественное наследование, но обработка C++ его является часто неловкой и иногда озадачивающей.
, В то время как я столкнулся со случаями, где множественное наследование очень удобно, они на самом деле довольно редки. Это вероятно, потому что я предпочитаю использовать другие методы разработки, когда мне действительно не нужно множественное наследование. Я действительно предпочитаю стараться не путать конструкции языка, и легко создать случаи наследования, где необходимо прочитать руководство действительно хорошо для выяснения то, что продолжается.
См. w: Множественное наследование .
Множественное наследование получило критику и как таковой, не реализован на многих языках. Критические замечания включают:
- Увеличенная сложность
- семантическая неоднозначность, часто получаемая в итоге как ромбовидная проблема .
- Неспособность явно наследоваться многократно единому классу
- Порядок наследования, изменяющего семантику класса.
Множественное наследование на языках с C++ / конструкторы стиля Java усиливает проблему наследования конструкторов и конструктора, объединяющего в цепочку, таким образом, создавая обслуживание и проблемы расширяемости на этих языках. Объекты в отношениях наследования со значительно переменными способами строительства трудно реализовать при конструкторе, объединяющем парадигму в цепочку.
современный способ разрешить это для использования интерфейса (чистый абстрактный класс) как интерфейс COM и Java.
я могу сделать другие вещи вместо этого?
Да, Вы можете. Я собираюсь украсть от GoF.
Нет никакой причины избежать его, и это может быть очень полезно в ситуациях. Необходимо знать о потенциальных проблемах все же.
самый большой, являющийся ромбом смерти:
class GrandParent;
class Parent1 : public GrandParent;
class Parent2 : public GrandParent;
class Child : public Parent1, public Parent2;
у Вас теперь есть две "копии" GrandParent в Ребенке.
C++ думал об этом, хотя и позволяет Вам сделать виртуальное наследование для обхождения проблем.
class GrandParent;
class Parent1 : public virtual GrandParent;
class Parent2 : public virtual GrandParent;
class Child : public Parent1, public Parent2;
Всегда рассматривают Ваш дизайн, гарантируют, что Вы не используете наследование, чтобы экономить на повторном использовании данных. Если можно представить то же самое с составом (и обычно Вы можете), это быть намного лучшим подходом.
От интервью с Bjarne Stroustrup :
Люди вполне правильно говорят, что Вам не нужно множественное наследование, потому что что-либо, что можно сделать со множественным наследованием, которое можно также сделать с единичным наследованием. Вы просто используете прием делегации, который я упомянул. Кроме того, Вам не нужно никакое наследование вообще, потому что что-либо, что Вы делаете с единичным наследованием, которое можно также обойтись без наследования путем передачи через класс. На самом деле Вам не нужны никакие классы также, потому что можно сделать все это с указателями и структурами данных. Но почему Вы хотели бы сделать это? Когда удобно использовать средства языка? Когда Вы предпочли бы обходное решение? Я видел случаи, где множественное наследование полезно, и я даже видел случаи, где довольно сложное множественное наследование полезно. Обычно я предпочитаю использовать средства, предлагаемые языком выполнению обходных решений