WedX - журнал о программировании и компьютерных науках

Как инициализировать массив указателей на классы?

данного класса (например, с именем X), я хочу выделить массив следующим образом:
X** array=new X*[20];

Давайте посмотрим на следующую функцию:

void Func(){  
  X** array=new X*[2];  
  X[0]=& X(5);
  X[1]=& X(3);
}  

Это нормально делать так или я должен делать это с new?

04.06.2018

  • Возможный дубликат C++ Как установить нулевой массив указателей в списке инициализаторов подобным образом? 04.06.2018
  • @ Рон, я знаю, что могу сделать это с вектором, но я прошу массив, чтобы научиться с ним работать. 04.06.2018
  • @Ron X** array=new X*[20]; это не определено как массив 20 указателей на X? 04.06.2018
  • Редактировать примечание: первая часть вопроса была дубликатом - см. комментарий Лантинга - так что это удалено. Пожалуйста, пересмотрите закрытое голосование в свете редактирования. 04.06.2018
  • Примечание: вместо необработанного массива вы рассматривали std::array или std::vector? Оба менее проблематичны, чем ваши необработанные указатели. Если вы объедините их с умными указателями (std::unique_ptr или std::shared_ptr, в зависимости от варианта использования), вам также не нужно заботиться о правильном удалении объекта... 04.06.2018
  • Если вам нужен чистый массив из 20 nullptrs в X => X *arr[20] = {};, arr имеет тип массива из 20 указателей на X, а не указатель на указатель на X 04.06.2018
  • Это даже компилируется? Нельзя брать адрес временного. И даже если бы вы могли, то нет, это не сработало бы. Вы бы использовали адрес мертвого объекта. 04.06.2018

Ответы:


1

Дело в том, что когда вы делаете что-то вроде этого:

X foo(5);
X[0] = &foo;

(что я полагаю, это то, что вы хотите сказать)

X[0] возьмет адрес foo, который является локальной переменной, которая будет существовать только в рамках вашей функции. И если бред не говорил, не компилируется. (-fpermissive)

Таким образом, после последней инструкции вашей функции использование этого указателя будет неопределенным

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

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

Другим решением может быть их динамическое выделение.

X[0] = new X(5);
04.06.2018
  • Можете ли вы объяснить, как я могу сделать это, например, без new? (или что я не могу сделать это без new [вообще], потому что это временный объект) 04.06.2018
  • @AskMath: программирование работает не так. Сначала вы должны определить, что должно храниться в array. Если вам просто нужны два объекта X, вы должны определить X array[2];. Если по какой-то причине вы знаете, что вам нужно сохранить два результата new X, вам понадобится X* array[2]. 04.06.2018
  • @MSalters, а для определения X* array[2] я должен определить конструктор по умолчанию в классе X? 04.06.2018
  • @AskMath: Вам даже не понадобится полное определение class X! Вы можете использовать предварительное объявление, то есть class X;. Определение class X необходимо только тогда, когда вам нужны фактические объекты X, но опять же, обычно этот вопрос вообще не возникает. 04.06.2018
  • Вот реализация с некоторыми комментариями @Jarod42 правда, я исправил свои ошибки 04.06.2018
  • @FabianleMaux: я отредактировал разметку в вашем вопросе, но не согласен с содержанием. Нулевая инициализация сделает указатели равными nullptr, просто это не единственная возможная инициализация. Это не зависит от компилятора или платформы. 04.06.2018
  • @MSalters Можете ли вы объяснить, что вы сказали, пожалуйста? 04.06.2018
  • Когда вы говорите об нулевой инициализации, вы говорите о не-инициализации? @MSalters 04.06.2018
  • @FabianleMaux: см. en.cppreference.com/w/cpp/language/zero_initialization. Если вы еще недостаточно знакомы с C++, чтобы знать эти термины, вам может быть сложно ответить на вопросы по C++ в StackOverflow. 04.06.2018
  • Отредактировано благодаря вам @MSalters 05.06.2018
  • Новые материалы

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


    Для любых предложений по сайту: [email protected]