Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > По поводу наследования |
Автор: Salatovec 25.9.2013, 10:36 | ||
Доброго всем времени суток, столкнулся с такой проблемой - вот код:
Можно ли при сохранении структуры классов создать массив фигур без указателей и конструкций аля new-delete? Заранее спасибо за помощь! |
Автор: Earnest 25.9.2013, 10:40 |
Без указателей в один массив разные типы загнать нельзя. А вот без delete обойтись вполне можно. Используй умные указатели, например из буста. Насчет new - если есть желание и смысл заморачиваться, можно какую-нибудь фабрику организовать. Но где-то все равно будет new, естественно. |
Автор: Salatovec 25.9.2013, 10:56 | ||
Earnest, спасибо, с этим моментом понял. Тогда попробую с другой стороны зайти. При использовании такой структуры проблема возникла при реализации возможности удаления из массива выборочного элемента. Например:
А как дальше? Нужно же поменять размер массива. Переместить элементы 2 и 3 на место 1 и 2 соответственно. Это я победить так и не смог. |
Автор: Guinness 25.9.2013, 11:06 |
http://en.wikipedia.org/wiki/Erase-remove_idiom |
Автор: vinter 25.9.2013, 12:17 |
+ std::unique_ptr хранить в векторе, а не голые указатели. |
Автор: Salatovec 25.9.2013, 12:37 |
Guinness, а можно небольшой примерчик использования? vinter, это не буст случаем? |
Автор: vinter 25.9.2013, 12:47 | ||
Это не буст, это стандартный C++. Правда требует более-менее свежего компилятора. P.S. я не собирал пример. |
Автор: Guinness 25.9.2013, 13:20 |
Точно? Это же аналог auto_ptr с некоторыми улучшениями? А такой тип указателей не рекомендуется хранить в контейнерах. Лучше, std::shared_ptr( если C++11 ) или boost::shared_ptr( в более ранних версиях ). Я же вроде ссылку дал на вики с примером. Или какой-то конкретный момент непонятен? |
Автор: vinter 25.9.2013, 13:27 | ||
Это то, чем должен был быть auto_ptr, но так и не стал в связи с отсутствием понятия "перемещение" в ранних версиях стандарта. Насчёт "не рекомендуется использовать": впервые слышу, какие аргументы? std::shared_ptr накладывает определенные накладные расходы, которые в данном случае не нужны. Если нет потребности в std::shared_ptr его использования стоит избегать, это не бесплатная сущность. В отличие от std::unique_ptr. |
Автор: azesmcar 25.9.2013, 14:09 |
![]() std::unique_ptr как раз таки можно хранить в контейнерах. Добавлено через 1 минуту и 45 секунд http://en.cppreference.com/w/cpp/memory/unique_ptr Typical uses of std::unique_ptr include:
|
Автор: Guinness 25.9.2013, 14:21 | ||
Так, я там проглядел, но у unique_ptr есть следующие объявления:
Т.е. копирование запрещено как таковое. Получается, что мой пример с for_each мне выкинет ошибку на этапе компиляции? А контейнеры в любом случае будут возвращать ссылку на unique_ptr. Получается избегаем проблем связанных с auto_ptr. |
Автор: vinter 25.9.2013, 14:21 | ||||||||
Нет, он не имеет конструктора копирования, только конструктор перемещения, что делает его тем, чем auto_ptr так и не стал. Вы не можете его использовать неправильно неявно, в отличие от auto_ptr
Не правы, приведённые пример просто не соберется, по причине, которая приведена выше. А вот так соберётся:
Чтобы Ваш пример собирался и работал for_each должен выглядеть как-то так:
Само собой, никакого std::move в стандартной версии нет ибо это бы ломало контейнеры. А так контейнеры вполне хорошо работают с объектами, которые не могут быть скопированы, а могут лишь быть перемещёнными. |
Автор: Guinness 25.9.2013, 14:24 | ||
Ну да, либо функция должна принимать ссылку на unique_ptr. |
Автор: Salatovec 25.9.2013, 14:55 | ||
vinter, спасибо за пример, попробую в свободное от работы время.
Не заметил ссылку, спасибо. |
Автор: Guinness 25.9.2013, 16:52 |
Для тех кому интересна информация об умных указателях, нашёл статейки, может кому пригодится: http://eli.thegreenplace.net/2012/06/20/c11-using-unique_ptr-with-standard-library-containers/ http://herbsutter.com/2013/05/29/gotw-89-solution-smart-pointers/ |
Автор: vinter 25.9.2013, 17:16 |
тогда еще свою http://scrutator.me/post/2012/01/18/smart-pointers.aspx оставлю тут |
Автор: NoviceF 26.9.2013, 15:03 | ||||
Никто не прокомментировал, но
Синтаксическая ошибка, так что пример вообще не должен компилиться. Но даже, если здесь использовать
Программа будет падать, т.к. это попытка удалить память, выделенную на стеке при помощи delete. Но даже если программа не упадёт, будет утечка памяти, т.к. элементы массива в коде не удаляются. |
Автор: akizelokro 26.9.2013, 19:23 | ||
Да в общем случае можно, но это будет неудобно (не так быстро или ещё варианты). Да и скажем, в одном из вариантов не обойтись без указателей, а в другом случае нужны ссылки. Вообще "std::vector" яляется не более чем оболочкой для массива с переменной, указывающей количество используемых элементов в массиве. Далее, С в помощь настойчивому программисту и подобные задачи уже писались до ООП. И решались не так уж сложно. Как сделать смещение в массиве с удалением элемента - это просто. Но это уже не ООП в чистом виде. malloc в зубы - и вот тебе уже capacity контейнера vector А чем вызвана причина необходимости именно такого подхода? Может, сначала стоит оценить реальную мотивировку? |
Автор: Salatovec 30.9.2013, 09:54 | ||||||
А как тогда должна выглядеть правильная очистка? Во всех примерах, подобного рода, память освобождали именно таким образом ![]() |
Автор: bsa 30.9.2013, 10:04 |
Salatovec, delete figures[1]; delete figures[] - синтаксически неверно, а delete []figures можно применять только после figures = new Figure*[4]; А у тебя автоматический массив указателей. Он уничтожается тоже автоматически. Но объекты, на которые ссылаются члены массива уничтожать надо вручную. |
Автор: Salatovec 30.9.2013, 13:00 | ||
bsa, правильно ли я понимаю, что нужно сделать так:
Так? |
Автор: vinter 30.9.2013, 13:08 |
так |
Автор: bsa 2.10.2013, 22:17 |
Salatovec, да. Правильно. Но всеже рекомендую использовать умные указатели ВЕЗДЕ. |