Как передать массив в класс в php?
Поэтому, когда я вызываю эту функцию ispis(), она ничего не делает, но когда я эхо внутри функции __constructor, она показывает правильные значения всего введенного. Также, когда я комментирую первые три строки выше //$ daniel = new User («ivan», «22»); line и раскомментируйте это, ispis() работает просто отлично. Было бы хорошо, если бы кто-нибудь мог объяснить мне, почему это происходит. Tnx заранее 🙂
По внешнему виду вашего кода вы пытаетесь передать два новых пользовательских экземпляра новому пользователю («daniel»).
Таким образом, в основном пользователь ожидает 4 аргумента (возраст, имя, высота, вес). Вы правильно создали Луку и Ивана, но вы передаете этих двух Пользователей в качестве аргументов при попытке создать Даниэля. Вы даете ему Лука и Ивана, когда ему нужны возраст, имя, рост и вес.
Если вы просто хотите передать массив конструктору, просто передайте его как аргумент нового экземпляра:
Ваш вопрос кажется немного неоднозначным, но, возможно, вы хотите создать объект из массива аргументов.
Роберт просто ответил, и его метод — тот, который я использую в личном MVC для определения конструкции, или по-другому существует также этот метод, который я всегда использую в своем MVC: P. Btw, я думаю, что вы немного путаетесь с классы.
Как передать массив в класс в C++
Когда я создаю класс, я хотел бы иметь возможность хранить массив в этом классе. Возможно ли это?
Например. Если у меня есть класс array для хранения массива из моей основной функции
2 ответа
используйте std::array вместо необработанного массива. Он похож на необработанный массив, но поддается копированию и имеет полезные функции-члены.
или, может быть, std::vector , если вы хотите иметь возможность изменять размер по желанию
Я не уверен, что вы делаете, поэтому трудно дать хороший совет. Вы можете передать необработанный массив по ссылке, указателю и счетчику, паре итераторов.
Да, но вы должны либо динамически выделять массив при создании класса, либо массив всегда должен быть одинакового размера.
Вероятно, это именно то, что вам нужно, но обратите внимание, что вам почти наверняка понадобится пользовательский конструктор копирования и оператор присваивания, чтобы вы не делили память между несколькими экземплярами этого класса. Лучшим способом может быть создание функции копирования, которую могут использовать оба.
10.2– Массивы (часть 2)
Данный урок продолжает обсуждение массивов, начатое в уроке «10.1 – Массивы (часть 1)».
Инициализация фиксированных массивов
Элементы массива обрабатываются так же, как обычные переменные, и поэтому при создании они не инициализируются.
Один из способов «инициализировать» массив – делать это поэлементно:
Однако это утомительно, особенно когда массив становится больше. Более того, это не инициализация, а присваивание. Присваивания не работают, если массив является константным.
К счастью, C++ предоставляет более удобный способ инициализации массивов целиком с помощью списка инициализаторов. В следующем примере массив инициализируется теми же значениями, что и в приведенном выше:
Если в списке инициализаторов больше, чем может вместить массив, компилятор выдаст ошибку.
Однако, если в списке инициализаторов меньше, чем может содержать массив, оставшиеся элементы инициализируются значением 0 (или любым другим значением, в которое 0 преобразуется для нецелочисленного базового типа – например, 0.0 для double ). Это называется нулевой инициализацией.
Следующий пример показывает это в действии:
Эта программа печатает:
Следовательно, чтобы инициализировать все элементы массива нулями, вы можете сделать так:
Если список инициализаторов опущен, элементы не инициализируются, если они не относятся к типу класса.
Лучшая практика
Инициализируйте массивы явно, даже если они будут инициализированы без списка инициализаторов.
Опущенное значение длины
Если вы инициализируете фиксированный массив элементов с помощью списка инициализаторов, компилятор может определить длину массива за вас, и вы можете не указывать длину массива явно.
Следующие две строки эквивалентны:
Это не только экономит время на ввод текста, но и означает, что вам не нужно обновлять длину массива, если позже вы добавите или удалите элементы.
Массивы и перечисления
Одна из серьезных проблем с документированием массивов заключается в том, что целочисленные индексы не предоставляют программисту никакой информации о значении индекса. Рассмотрим класс из 5 учеников:
Кого представляет testScores[2] ? Не ясно.
Это можно решить, создав перечисление, в котором перечислители сопоставляются с каждым из возможных индексов массива:
Таким образом, становится намного понятнее, что представляет каждый из элементов массива. Обратите внимание, что был добавлен дополнительный перечислитель с именем max_students . Этот перечислитель используется во время объявления массива, чтобы гарантировать, что массив имеет правильную длину (так как длина массива должна быть на единицу больше, чем наибольший индекс). Это полезно как для документирования, так и потому, что при добавлении еще одного перечислителя размер массива будет изменен автоматически:
Обратите внимание, что этот «трюк» работает только в том случае, если вы не изменяете значения перечислителей вручную!
Массивы и классы перечислений
Классы перечислений не имеют неявного преобразования в целочисленный тип, поэтому, если вы попробуете следующее:
Вы получите ошибку компиляции. Это можно решить, используя static_cast для преобразования перечислителя в целочисленный тип:
Однако делать так довольно утомительно, поэтому может быть лучше использовать обычное перечисление внутри пространства имен:
Передача массивов в функцию
Хотя передача массива в функцию на первый взгляд выглядит так же, как передача обычной переменной, но под капотом C++ обрабатывает массивы по-другому.
Когда обычная переменная передается по значению, C++ копирует значение аргумента в параметр функции. Поскольку параметр является копией, изменение значения параметра не приводит к изменению значения исходного аргумента.
Однако, поскольку копирование больших массивов может быть очень дорогостоящим, C++ не копирует массив при его передаче в функцию. Вместо этого передается исходный массив. Это имеет побочный эффект, поскольку функциям позволяется напрямую изменять значение элементов массива!
Следующий пример иллюстрирует эту концепцию:
В приведенном выше примере value в main() не изменяется, потому что значение параметра в функции passValue() было копией значения переменной в функции main() , а не исходной переменной. Однако, поскольку параметр массива в функции passArray() является исходным массивом, passArray() может напрямую изменять значение элементов!
Почему это происходит, связано с тем, как массивы реализованы в C++, и мы еще вернемся к этой теме после того, как рассмотрим указатели. На данный момент вы можете рассматривать это как причуду языка.
В качестве отступления от темы: если вы хотите убедиться, что функция не изменяет переданные в нее элементы массива, вы можете сделать массив константным:
Определение длины массива
Для определения длины массивов может использоваться функция std::size() из заголовка <iterator> .
Эта программа напечатает:
Обратите внимание, что из-за того, как C++ передает массивы функциям, это не будет работать для массивов, которые были переданы функции!
std::size() будет работать и с другими типами объектов (такими как std::array и std::vector ), и она вызовет ошибку компиляции, если вы попытаетесь использовать ее с фиксированным массивом, который был передан в функцию! Обратите внимание, что std::size() возвращает значение без знака. Если вам нужно значение со знаком, вы можете либо выполнить приведение типа результата, либо, начиная с C++20, использовать std::ssize() (означает «signed size», размер со знаком).
std::size() была добавлена в C++17. Если вы всё еще используете старый компилятор, вам придется использовать вместо нее оператор sizeof . sizeof не так прост в использовании, как std::size() , и есть несколько вещей, на которые следует обратить внимание. Если вы используете компилятор с поддержкой C++17, можете перейти к разделу «Индексирование массива вне допустимого диапазона».
Оператор sizeof может использоваться с массивами, в этом случае он вернет общий размер массива (длина массива, умноженная на размер элемента).
На машине с 4-байтовыми int и 8-байтовыми указателями эта программа напечатала:
Если размеры типов у вас отличаются, вы можете получить другой результат.
Небольшой трюк: мы можем определить длину фиксированного массива, разделив размер всего массива на размер элемента массива:
Как это работает? Во-первых, обратите внимание, что размер всего массива равен длине массива, умноженной на размер элемента. Проще говоря: размер массива = длина массива * размер элемента.
Используя математику, мы можем изменить это уравнение: длина массива = размер массива / размер элемента. sizeof(array) – это размер массива, а sizeof(array[0]) – это размер элемента, поэтому наше уравнение принимает вид длина массива = sizeof(array) / sizeof(array[0]) . Обычно в качестве элемента массива мы используем нулевой элемент, поскольку это единственный гарантированно существующий элемент независимо от длины массива.
Обратите внимание, что это будет работать только в том случае, если массив является массивом фиксированной длины, и вы выполняете этот трюк в той же функции, в которой массив объявлен (о том, почему это ограничение существует, мы поговорим подробнее в следующем уроке этой главы).
Когда sizeof используется с массивом, который был передан функции, он не вызывает ошибок, как std::size() . Вместо этого он возвращает размер указателя.
Снова предполагая размер указателя 8 байт и размер int 4 байта, этот код напечатает:
Примечание автора
Правильно настроенный компилятор должен вывести предупреждение, если вы попытаетесь использовать sizeof() для массива, переданного функции.
Расчет в main() был правильным, но sizeof() в printSize() вернул 8 (это размер указателя), а 8, деленное на 4, равно 2.
По этой причине будьте осторожны при использовании sizeof() для массивов!
Примечание. В общем случае термины «размер массива» и «длина массива» чаще всего используются для обозначения длины массива (размер массива в большинстве случаев бесполезен, за исключением показанного выше трюка).
Индексирование массива вне допустимого диапазона
Помните, что массив длины N имеет элементы от 0 до N-1. Итак, что произойдет, если вы попытаетесь получить доступ к элементу массива с индексом за пределами этого диапазона?
Рассмотрим следующую программу:
В этой программе наш массив имеет длину 5, но мы пытаемся записать простое число в шестой элемент (индекс 5).
C++ не выполняет никаких проверок, чтобы убедиться, что ваши индексы допустимы для длины вашего массива. Таким образом, в приведенном выше примере значение 13 будет вставлено в память там, где существовал бы шестой элемент. Когда это произойдет, вы получите неопределенное поведение – например, это может перезаписать значение другой переменной или вызвать сбой вашей программы.
Хотя это случается реже, но C++ также позволяет использовать отрицательный индекс с такими же нежелательными результатами.
Правило
При использовании массивов убедитесь, что ваши индексы допустимы для диапазона вашего массива!
Небольшой тест
Вопрос 1
Объявите массив для хранения максимальной температуры (с точностью до десятых долей градуса) для каждого дня в году (предположим, в году 365 дней). Инициализируйте массив значением 0.0 для каждого дня.
Вопрос 2
Создайте перечисление с именами следующих животных: курица (chicken), собака (dog), кошка (cat), слон (elephant), утка (duck) и змея (snake). Поместите перечисление в пространство имен. Определите массив с элементом для каждого из этих животных и используйте список инициализаторов, чтобы инициализировать каждый элемент для хранения количества ног, которое есть у животного.
Напишите функцию main , которая печатает количество ног слона, используя перечислитель.