![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
Salatovec |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 213 Регистрация: 9.1.2008 Репутация: нет Всего: -1 |
Доброго всем времени суток, столкнулся с такой проблемой - вот код:
Можно ли при сохранении структуры классов создать массив фигур без указателей и конструкций аля new-delete? Заранее спасибо за помощь! |
|||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Без указателей в один массив разные типы загнать нельзя. А вот без delete обойтись вполне можно. Используй умные указатели, например из буста. Насчет new - если есть желание и смысл заморачиваться, можно какую-нибудь фабрику организовать. Но где-то все равно будет new, естественно.
-------------------- ... |
|||
|
||||
Salatovec |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 213 Регистрация: 9.1.2008 Репутация: нет Всего: -1 |
Earnest, спасибо, с этим моментом понял. Тогда попробую с другой стороны зайти. При использовании такой структуры проблема возникла при реализации возможности удаления из массива выборочного элемента. Например:
А как дальше? Нужно же поменять размер массива. Переместить элементы 2 и 3 на место 1 и 2 соответственно. Это я победить так и не смог. |
|||
|
||||
Guinness |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 310 Регистрация: 21.6.2009 Где: Зеленоград Репутация: нет Всего: 10 |
||||
|
||||
vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
+ std::unique_ptr хранить в векторе, а не голые указатели.
|
|||
|
||||
Salatovec |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 213 Регистрация: 9.1.2008 Репутация: нет Всего: -1 |
Guinness, а можно небольшой примерчик использования?
vinter, это не буст случаем? |
|||
|
||||
vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
Это не буст, это стандартный C++. Правда требует более-менее свежего компилятора. P.S. я не собирал пример. Это сообщение отредактировал(а) vinter - 25.9.2013, 12:48 |
|||
|
||||
Guinness |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 310 Регистрация: 21.6.2009 Где: Зеленоград Репутация: нет Всего: 10 |
Точно? Это же аналог auto_ptr с некоторыми улучшениями? А такой тип указателей не рекомендуется хранить в контейнерах. Лучше, std::shared_ptr( если C++11 ) или boost::shared_ptr( в более ранних версиях ). Я же вроде ссылку дал на вики с примером. Или какой-то конкретный момент непонятен? |
|||
|
||||
vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
Это то, чем должен был быть auto_ptr, но так и не стал в связи с отсутствием понятия "перемещение" в ранних версиях стандарта. Насчёт "не рекомендуется использовать": впервые слышу, какие аргументы? std::shared_ptr накладывает определенные накладные расходы, которые в данном случае не нужны. Если нет потребности в std::shared_ptr его использования стоит избегать, это не бесплатная сущность. В отличие от std::unique_ptr. |
|||
|
||||
Guinness |
|
||||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 310 Регистрация: 21.6.2009 Где: Зеленоград Репутация: нет Всего: 10 |
auto_ptr ведет себя вот так:
Судя, по описанию unique_ptr он ведет себя схожим образом:
Может я чего-то не допонял или не так перевел? Но вызов foreach для вектора как показано ниже приведет к печальным последствиям:
Или я не прав? Это сообщение отредактировал(а) Guinness - 25.9.2013, 14:05 |
||||||||
|
|||||||||
azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
![]() std::unique_ptr как раз таки можно хранить в контейнерах. Добавлено через 1 минуту и 45 секунд http://en.cppreference.com/w/cpp/memory/unique_ptr Typical uses of std::unique_ptr include:
|
|||
|
||||
Guinness |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 310 Регистрация: 21.6.2009 Где: Зеленоград Репутация: нет Всего: 10 |
Так, я там проглядел, но у unique_ptr есть следующие объявления:
Т.е. копирование запрещено как таковое. Получается, что мой пример с for_each мне выкинет ошибку на этапе компиляции? А контейнеры в любом случае будут возвращать ссылку на unique_ptr. Получается избегаем проблем связанных с auto_ptr. |
|||
|
||||
vinter |
|
||||||||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
Нет, он не имеет конструктора копирования, только конструктор перемещения, что делает его тем, чем auto_ptr так и не стал. Вы не можете его использовать неправильно неявно, в отличие от auto_ptr
Не правы, приведённые пример просто не соберется, по причине, которая приведена выше. А вот так соберётся:
Чтобы Ваш пример собирался и работал for_each должен выглядеть как-то так:
Само собой, никакого std::move в стандартной версии нет ибо это бы ломало контейнеры. А так контейнеры вполне хорошо работают с объектами, которые не могут быть скопированы, а могут лишь быть перемещёнными. |
||||||||
|
|||||||||
Guinness |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 310 Регистрация: 21.6.2009 Где: Зеленоград Репутация: нет Всего: 10 |
||||
|
||||
Salatovec |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 213 Регистрация: 9.1.2008 Репутация: нет Всего: -1 |
||||
|
||||
Guinness |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 310 Регистрация: 21.6.2009 Где: Зеленоград Репутация: нет Всего: 10 |
Для тех кому интересна информация об умных указателях, нашёл статейки, может кому пригодится:
unique_ptr unique_ptr vs shared_ptr Это сообщение отредактировал(а) Guinness - 25.9.2013, 16:53 |
|||
|
||||
vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
тогда еще свою статью оставлю тут
|
|||
|
||||
NoviceF |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 13.3.2012 Где: Ростов-на-Дону Репутация: нет Всего: 2 |
Никто не прокомментировал, но
Синтаксическая ошибка, так что пример вообще не должен компилиться. Но даже, если здесь использовать
Программа будет падать, т.к. это попытка удалить память, выделенную на стеке при помощи delete. Но даже если программа не упадёт, будет утечка памяти, т.к. элементы массива в коде не удаляются. |
||||
|
|||||
akizelokro |
|
|||
![]() Крокодил ![]() ![]() Профиль Группа: Участник Сообщений: 761 Регистрация: 30.7.2007 Репутация: 1 Всего: 5 |
Да в общем случае можно, но это будет неудобно (не так быстро или ещё варианты). Да и скажем, в одном из вариантов не обойтись без указателей, а в другом случае нужны ссылки. Вообще "std::vector" яляется не более чем оболочкой для массива с переменной, указывающей количество используемых элементов в массиве. Далее, С в помощь настойчивому программисту и подобные задачи уже писались до ООП. И решались не так уж сложно. Как сделать смещение в массиве с удалением элемента - это просто. Но это уже не ООП в чистом виде. malloc в зубы - и вот тебе уже capacity контейнера vector А чем вызвана причина необходимости именно такого подхода? Может, сначала стоит оценить реальную мотивировку? Это сообщение отредактировал(а) akizelokro - 26.9.2013, 19:32 -------------------- a = a + b; b = a - b; a = a - b; |
|||
|
||||
Salatovec |
|
||||||
Бывалый ![]() Профиль Группа: Участник Сообщений: 213 Регистрация: 9.1.2008 Репутация: нет Всего: -1 |
А как тогда должна выглядеть правильная очистка? Во всех примерах, подобного рода, память освобождали именно таким образом ![]() |
||||||
|
|||||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Salatovec, delete figures[1];
delete figures[] - синтаксически неверно, а delete []figures можно применять только после figures = new Figure*[4]; А у тебя автоматический массив указателей. Он уничтожается тоже автоматически. Но объекты, на которые ссылаются члены массива уничтожать надо вручную. |
|||
|
||||
Salatovec |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 213 Регистрация: 9.1.2008 Репутация: нет Всего: -1 |
bsa, правильно ли я понимаю, что нужно сделать так:
Так? |
|||
|
||||
vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
так
|
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Salatovec, да. Правильно.
Но всеже рекомендую использовать умные указатели ВЕЗДЕ. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |