Как правильно обратиться к функции в классе?
В самом Unity задаю предметы для переменной items
и при использовании inv.AddItem(0, inv.items[1], 1); получаю следующую ошибку:
ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
Я так понял, он считает, что не существует предмета с id 1 в items. Но это не так. Что я делаю не правильно?
17.7 – Вызов унаследованных функций и переопределение поведения
По умолчанию производные классы наследуют все поведения, определенные в базовом классе. В этом уроке мы более подробно рассмотрим, как выбираются функции-члены, а также как мы можем использовать это для изменения поведения в производном классе.
Вызов функции базового класса
Когда функция-член вызывается с объектом производного класса, компилятор сначала проверяет, существует ли этот член в производном классе. Если нет, он начинает переходить по цепочке наследования и проверять, определен ли член в каком-либо из родительских классов. И использует первый найденный.
Рассмотрим следующий пример:
Эта программа печатает
Когда вызывается derived.identify() , компилятор проверяет, определена ли функция identify() в классе Derived . Ее там нет. Затем он начинает искать наследуемые классы (в данном случае это Base ). Base определил функцию identify() , поэтому компилятор использует ее. Другими словами, Base::identify() использовалась, потому что Derived::identify() не существует.
Это означает, что если поведение, обеспечиваемое базовым классом, достаточно, мы можем просто использовать его.
Переопределение поведения
Однако если бы мы определили Derived::identify() в классе Derived , то использовалась бы эта функция.
Это означает, что мы можем заставить функции работать с нашими производными классами по-другому, переопределив их в производных классах!
В нашем примере выше было бы более правильно, если бы derived.identify() напечатала " I am a Derived ". Давайте изменим функцию identify() в классе Derived , чтобы она возвращала правильный ответ, когда мы вызываем identify() с объектом Derived .
Чтобы изменить в производном классе способ работы функции, определенной в базовом классе, просто переопределите эту функцию в производном классе.
Вот тот же пример, что и выше, с использованием новой функции Derived::identify() :
Обратите внимание, что когда вы переопределяете функцию в производном классе, производная функция не наследует спецификатор доступа функции с тем же именем в базовом классе. Она использует любой спецификатор доступа, который определяется в производном классе. Следовательно, функция, которая определена как закрытая в базовом классе, может быть переопределена как открытая в производном классе, и наоборот!
Добавление дополнений к существующей функциональности
Иногда мы не хотим полностью заменять функцию базового класса, а вместо этого хотим добавить к ней дополнительный функционал. Обратите внимание, что в приведенном выше примере Derived::identify() полностью скрывает Base::identify() ! Возможно, это не то, что нам нужно. Допускается, чтобы наша производная функция вызывала базовую версию функции с тем же именем (для повторного использования кода), а затем добавляла к ней дополнительный функционал.
Чтобы производная функция вызывала базовую функцию с тем же именем, просто выполните обычный вызов функции, но добавив перед именем функции квалификатор области видимости (имя базового класса и два двоеточия). В следующем примере переопределяется Derived::identify() , поэтому она сначала вызывает Base::identify() , а затем выполняет свои собственные дополнительные действия.
Теперь рассмотрим следующий пример:
Когда выполняется derived.identify() , вызов преобразуется в Derived::identify() . Однако первое, что делает Derived::identify() , – это вызывает Base::identify() , который выводит " I am a Base ". Когда Base::identify() возвращает управление, Derived::identify() продолжает выполнение и печатает " I am a Derived ".
Это должно быть довольно просто. Почему нам нужно использовать оператор разрешения области видимости ( :: )? Если бы мы определили Derived::identify() следующим образом:
Вызов функции identify() без квалификатора разрешения области видимости по умолчанию будет использовать identify() в текущем классе, которой будет Derived::identify() . Это приведет к тому, что Derived::identify() вызовет себя, что приведет к бесконечному циклу!
Есть одна хитрость, с которой мы можем столкнуться при попытке вызвать дружественные функции в базовых классах, такие как operator<< . Поскольку дружественные функции базового класса фактически не являются частью базового класса, использование квалификатора разрешения области видимости не сработает. Вместо этого нам нужен способ временно сделать так, чтобы наш класс Derived выглядел как Base , чтобы можно было вызвать правильную версию функции.
К счастью, это легко сделать с помощью static_cast . Например:
Поскольку Derived «является» Base , мы можем выполнить статическое приведение нашего объекта Derived в Base , чтобы вызывалась соответствующая версия operator<< , которая использует Base .
Re: C++ как обратиться к методу базового класса?

соберется, конечно-же, потому как сигнатуры методов одинаковые.
Вот так вот не соберется:
A *b = new B(); b->method1();
Re: C++ как обратиться к методу базового класса?
в общем, гляжу много знатоков C++ собралось 🙂
простите за беспокойство ещё раз.
код который я набросал — никогда не компилировался, это просто пояснение ситуации, ясное дело я забыл : public, но и без него меня прекрасно поняли. Я с с++ не на короткой ноге, в инете порылся, на вскидку не нашёл, попробовал написать parent::method1() и ещё несколько вариантов.. потом решил спросить здесь. Как только запостил сообщение — понял, что как раз так как я написал я и не попробовал. Попробовал — заработало, о чём и сообщил в следующем посте. Всем спасибо, тему можно считать закрытой.
Re: C++ как обратиться к методу базового класса?
не тот который накурился )
Re: C++ как обратиться к методу базового класса?
хотя оба анонимуса гонят. Как же он вызовет A::method1() из б? ведь метод 1 не объявлен как статический. Вот если virtual заменить на static, то всё работает.

Re: C++ как обратиться к методу базового класса?
Брат мой Андрей! Молю тебя, почитай какую-нибудь умную книжку или тьюториал какой-нибудь. Шож ты алхимией занимаешься, работает-не работает.
Re: C++ как обратиться к методу базового класса?
Дядя теодор, я умную (несколько умных) книжек конкретно по c++ читал около 6 лет назад, в бытность мою студентом. С тех пор много воды утекло и с с++ я как-то не встречался со времён первой своей работы, и хотя синтаксис у каждого языка свой, концепции объектно-ориентированного программирования, что в Java, что в С++, что в smalltalk что в php(прости меня патрик :), что в ruby остаются одинаковыми. А по синтаксису, если срочно, то и спросить не такой уж страшный грех и святой инквизицией вроде не карается пока..
Re: C++ как обратиться к методу базового класса?
в общем читать не вижу смысла.. через неделю навык владения языком почти полностью восстановится, а на умную книжку уйдёт около месяца. Да и фиг бы с ним, но ничего нового я не узнаю, поскольку всё(по теме с++ для новичков, для профи, страуструп, дейтл и дейтл ) уже прочитано.
NickTikhomirov / Qu(1-2),(4-5).md
Класс — это структура, в которую в языке С++ введены методы для обработки полей.
Ключевые слова для объявления класса:
- struct
- class
- union
И да, union тоже умеет в методы
В качестве ключевого слова может использоваться как struct, так и class. Разницы никакой кроме того, что у class все поля по умолчанию имеют статус доступа private, а у struct (и union) — по умолчанию public. Это единственная разница между классом и структурой.
Компоненты класса: поля и методы.
Инициализация полей происходит раньше конструктора.
Модификатор const на методе (в конце заголовка метода) запрещает ему обращаться к полям класса с целью изменений.
Модификатор mutable на поле класса (перед полем) позволяет методам с модификатором «const» изменять его.
Методы внутри класса и вне его.
Пример объвления метода внутри класса. Этот метод будет, по возможности, подставляемым — его текст компуктор будет просто брать и пихать в то место, где происходит вызов
Пример объвления метода вне класса. В его случае всё будет как обычно — передача управления на функцию, все дела.
Билет 2. Статусы доступа компонент класса. Операции для доступа к компонентам класса, примеры.
Свойство доступности определяет возможность доступа к полям и методам за пределами класса (через имя объекта или через указатель на объект или в производном классе).
Ключевые слова для объявления класса:
- public — Свободный доступ для методов, потомков и вызовов извне
- protected — Только для методов и потомков
- private — Только для методов
«Сеттеры» и «геттеры» (жарг.), от слов set и get. Не являются какими-то особыми фичами или ключевыми словами, а представляют собой скорее определённый стиль программирования и аттрибут «хорошего кода». То есть считается хорошим тоном сделать поля protected или private, а затем для каждого поля написать setX() и getX(), где X — название поля. Практическая польза — в этих функциях могут быть представлены какие-то проверки или преобразования для значений, чтобы, например, в поле класса не поставили неправильное число. «Геттеры» чаще всего делают с модификатором const.
Билет 4. Статические компоненты класса, назначение, пример.
Перед полем или методом можно дописать ключевое слово static — тогда он(о) станет станет статическим. На статические поля и методы распространяются модификаторы доступа.
Статическое поле существует в единственном числе вне зависимости от количества объектов класса. Для всех них оно одинаково. Получить к нему доступ можно либо через имя класса ( A::a ), либо через имя какого-нибудь объекта этого класса. Инициализировать статическое поле надо вне класса, потому что иначе будут происходить всякие странности вроде переинициализации поля с каждым созданным объектом.
Статический метод — такой метод, который может быть вызван по имени класса, даже если не создано ни одного объекта этого класса. Он не взаимодействует ни с какими полями и методами класса кроме статических. К нем можно обращаться точно так же, как к ст.полю.
Билет 5. Указатель this, примеры использования.
Из курса алгоритмических языков мы знаем, что функции хранятся в стеке, а ещё при вызове не-inline функции у нас происходит передача управления на функцию. Также мы знаем, что методы класса взаимодействуют с полями того объекта, для которого они вызваны. То есть мой геттер фамилии возвращает именно мою фамилию, а не, например, Толину. В связи с этим возникает вопрос — у нас что, все методы класса дублируются столько раз, сколько объектов мы создадим? Прям за каждый объект в стек функций докладывается ещё одна?
Ответ: нет. Просто у каждого (не static) метода есть секретный аргумент — указатель на конкретный объект. Когда мы вызываем метод для какого-то объекта, в него передаётся указатель на него — так функция понимает, с чьими конкретно полями она работает. Программисту тоже разрешено взаимодействовать с этим указателем через ключевое слово this, которое по умолчанию определено внутри каждого (не static) метода любого класса.