Название: Преждевременный вызов деструктора Отправлено: Даниил от Март 13, 2012, 14:06 Приветствую всех.
Появилась внезапная трабла - хочу запихать в вектор свой класс. Только вот незадача, как только я push_back'аю объект в вектор, тот вызывает деструктор, при чем имеется какая-то странная зависимость от количества "запинаных" объектов, посмотрите, подскажите - где тут засада. Код Вывод: Код: Delete Coord[0,0] Название: Re: Преждевременный вызов деструктора Отправлено: Пантер от Март 13, 2012, 14:09 Все правильно - вектор хранит копию объекта. При изменении вектора происходит перераспределение объектов копированием.
Название: Re: Преждевременный вызов деструктора Отправлено: Даниил от Март 13, 2012, 14:25 м-м-м, поставлю вопрос конкретней - что нужно сделать, чтобы можно было в векторе хранить самописные объекты.
Название: Re: Преждевременный вызов деструктора Отправлено: mutineer от Март 13, 2012, 14:27 м-м-м, поставлю вопрос конкретней - что нужно сделать, чтобы можно было в векторе хранить самописные объекты. Они уже сейчас там хранятся. В чем проблема-то? Название: Re: Преждевременный вызов деструктора Отправлено: Даниил от Март 13, 2012, 14:29 Ну, вобще проблема есть - т.к. там хранится не то, что туда запихивали:
Код: Coord[0,11669608] Название: Re: Преждевременный вызов деструктора Отправлено: ddrtn от Март 13, 2012, 14:31 Это потому, что у Вас неправильно определен конструктор копирования. в нем копируется только х
Название: Re: Преждевременный вызов деструктора Отправлено: mutineer от Март 13, 2012, 14:32 Ну, вобще проблема есть - т.к. там хранится не то, что туда запихивали: Код: Coord[0,11669608] Вектор копирует объекты. Причем не один раз (при перераспределении памяти) А у тебя неполный конструктор копирования Код
Название: Re: Преждевременный вызов деструктора Отправлено: Пантер от Март 13, 2012, 14:32 Coord(const Coord &c){x = c.x;} - а y игноришь, вот и получаешь мусор.
Название: Re: Преждевременный вызов деструктора Отправлено: Даниил от Март 13, 2012, 14:35 Спасибо. Прозрел. :P
Название: Re: Преждевременный вызов деструктора Отправлено: Пантер от Март 13, 2012, 14:38 В данном случае свой копирующий конструктор и опрератор присваивания не нужны, так как класс тривиален.
Название: Re: Преждевременный вызов деструктора Отправлено: Даниил от Март 13, 2012, 17:43 Да я класс обрезал, чтобы сюда не кидать 300 строк кода, а так да, только в теории нужно еще оператор == перегрузить, а то вектор может начать ругаться.
Название: Re: Преждевременный вызов деструктора Отправлено: Igors от Март 13, 2012, 17:55 Конструктор лучше оформить так
Код Тогда он годится и по умолчанию А оператор < написать проще, (а то у Вас голову можно сломать) Код Оператор == вектору не требуется, но в такого класса нужен все равно Название: Re: Преждевременный вызов деструктора Отправлено: m_ax от Март 13, 2012, 18:40 Конструктор лучше оформить так Код Тогда он годится и по умолчанию А оператор < написать проще, (а то у Вас голову можно сломать) Код Оператор == вектору не требуется, но в такого класса нужен все равно А оператор < вообще бредово определять для данного класса) Какая точка будет больше p1(10, 1) или p2(1, 10) ? Согласно вашей реализации p1 окажется больше.. Но с чего это вы нарушаете равноправие между x и y компонентами? И как конечный пользователь должен досмысливать поведение такого оператора для объекта точки? Это не логично. Название: Re: Преждевременный вызов деструктора Отправлено: m_ax от Март 13, 2012, 18:44 Да и ещё:
Обычно так не пишут: Код
Лучше так: Код
Название: Re: Преждевременный вызов деструктора Отправлено: Igors от Март 13, 2012, 18:58 А оператор < вообще бредово определять для данного класса) Не всегда концептуальность идет в такт с конкретикой/реализацией. Есть вектор точек, надо удалить повторяющиеся. Что будете делать без оператора < ? Или у Вас есть др. предложения как его определить? Так что потише там с "бредово" и.т.п. :)Какая точка будет больше p1(10, 1) или p2(1, 10) ? Согласно вашей реализации p1 окажется больше.. Но с чего это вы нарушаете равноправие между x и y компонентами? И как конечный пользователь должен досмысливать поведение такого оператора для объекта точки? Это не логично. Название: Re: Преждевременный вызов деструктора Отправлено: Даниил от Март 13, 2012, 19:02 :o Да я просто так обозвал класс - прекратите холивар!
Название: Re: Преждевременный вызов деструктора Отправлено: m_ax от Март 13, 2012, 19:47 :o Да я просто так обозвал класс - прекратите холивар! Да какой ещё холивар) Выпейте лучше стакан холодной воды) А оператор < вообще бредово определять для данного класса) Не всегда концептуальность идет в такт с конкретикой/реализацией. Есть вектор точек, надо удалить повторяющиеся. Что будете делать без оператора < ? Или у Вас есть др. предложения как его определить? Так что потише там с "бредово" и.т.п. :)Какая точка будет больше p1(10, 1) или p2(1, 10) ? Согласно вашей реализации p1 окажется больше.. Но с чего это вы нарушаете равноправие между x и y компонентами? И как конечный пользователь должен досмысливать поведение такого оператора для объекта точки? Это не логично. Тогда у меня вопрос: пусть есть вектор объектов (пусть просто обычных чисел), у которых нет оператора <, но есть операторы (=! ==) Можно ли выкинуть из вектора повторяющиеся элементы? И как Вам поможет определённый выше оператор < ? Название: Re: Преждевременный вызов деструктора Отправлено: Igors от Март 13, 2012, 20:14 Тогда у меня вопрос: пусть есть вектор объектов (пусть просто обычных чисел), у которых нет оператора <, но есть операторы (=! ==) Можно ли выкинуть из вектора повторяющиеся элементы? Поможет так что я могу спокойно вызывать std::sort, помещать в std::set/map и делать многое другое без всяких усилий. А без оператора < мне придется поизвращаться: писать функторы. или городить хеш или юзать С-шный qsort - все это гораздо менее удобно. Поэтому нет оснований избегать оператора < только на том веском основании что он, дескать, "недостаточно идейный" :)И как Вам поможет определённый выше оператор < ? Название: Re: Преждевременный вызов деструктора Отправлено: BRE от Март 13, 2012, 20:20 Тогда зачем его так усложнять?
Код
можно сделать проще: Код
Название: Re: Преждевременный вызов деструктора Отправлено: mutineer от Март 13, 2012, 20:59 Тогда у меня вопрос: пусть есть вектор объектов (пусть просто обычных чисел), у которых нет оператора <, но есть операторы (=! ==) Можно ли выкинуть из вектора повторяющиеся элементы? И как Вам поможет определённый выше оператор < ? оператор < более универсален - с его помощь можно сортировать, сравнивать, а так же проверять на равенство. А вот с помощью операторов сравнения только проверять на равенство Ну если в этих операторах нет странной логики, конечно:) Название: Re: Преждевременный вызов деструктора Отправлено: m_ax от Март 14, 2012, 00:47 Тогда у меня вопрос: пусть есть вектор объектов (пусть просто обычных чисел), у которых нет оператора <, но есть операторы (=! ==) Можно ли выкинуть из вектора повторяющиеся элементы? Поможет так что я могу спокойно вызывать std::sort, помещать в std::set/map и делать многое другое без всяких усилий. А без оператора < мне придется поизвращаться: писать функторы. или городить хеш или юзать С-шный qsort - все это гораздо менее удобно. Поэтому нет оснований избегать оператора < только на том веском основании что он, дескать, "недостаточно идейный" :)И как Вам поможет определённый выше оператор < ? Я бы сделал как-то так: Код Вывод Код
Теперь если заменить int на Point у которого есть оператор == то всё получится) Название: Re: Преждевременный вызов деструктора Отправлено: m_ax от Март 14, 2012, 01:11 Тогда у меня вопрос: пусть есть вектор объектов (пусть просто обычных чисел), у которых нет оператора <, но есть операторы (=! ==) Можно ли выкинуть из вектора повторяющиеся элементы? И как Вам поможет определённый выше оператор < ? оператор < более универсален - с его помощь можно сортировать, сравнивать, а так же проверять на равенство. А вот с помощью операторов сравнения только проверять на равенство Ну если в этих операторах нет странной логики, конечно:) И как Вы предлагаете сравнивать такие объекты, как вектора? И что значит отсортировать вектора? Имхо, конечно, но это бред) Название: Re: Преждевременный вызов деструктора Отправлено: Igors от Март 14, 2012, 12:29 можно сделать проще: Ну тогда и оператор == должен быть в мастьКод
Код Хмм... :) Код
Теперь если заменить int на Point у которого есть оператор == то всё получится) Вы явно превзошли др фанов STL. У них ракообразные конструкции хоть экономят пару строчек (иногда). У Вас наоборот, увеличивают, + вкупе с линейным перебором. Видимо, это неважно, главное - побольше template, итераторов и вообще - полной абстракции. :)Название: Re: Преждевременный вызов деструктора Отправлено: BRE от Март 14, 2012, 13:17 Ну тогда и оператор == должен быть в масть Почему? Операторы == и != можно определить и они будут отражать физическую и математическую суть такого сравнения, чего нельзя сказать о операторах < и >. Вот последние можно определять как захочется, мой вариант просто более оптимизированный чем твой.Название: Re: Преждевременный вызов деструктора Отправлено: Igors от Март 14, 2012, 13:39 Почему? Операторы == и != можно определить и они будут отражать физическую и математическую суть такого сравнения, чего нельзя сказать о операторах < и >. Вот последние можно определять как захочется, мой вариант просто более оптимизированный чем твой. Тогда выходит такКод Хотя формально не ошибка - как этим пользоваться? :) Видимо не стоит так уж гнаться за "сутью", проще понимать < как некоторое "отношение" которое может использоваться для упорядочивания Название: Re: Преждевременный вызов деструктора Отправлено: BRE от Март 14, 2012, 13:43 Видимо не стоит так уж гнаться за "сутью", проще понимать < как некоторое "отношение" которое может использоваться для упорядочивания Вот правильно.Тогда повторю вопрос: Для чего у тебя такая сложная логика в этом операторе (по сравнению с моим вариантом)? Название: Re: Преждевременный вызов деструктора Отправлено: Igors от Март 14, 2012, 14:12 Тогда повторю вопрос: Для чего у тебя такая сложная логика в этом операторе (по сравнению с моим вариантом)? В Вашем варианте в сортированном массиве возможен такой порядок(-1, 1) (-2, 2) (-1, 1) Название: Re: Преждевременный вызов деструктора Отправлено: BRE от Март 14, 2012, 14:13 В Вашем варианте в сортированном массиве возможен такой порядок Да и что?(-1, 1) (-2, 2) (-1, 1) Название: Re: Преждевременный вызов деструктора Отправлено: m_ax от Март 14, 2012, 14:20 можно сделать проще: Ну тогда и оператор == должен быть в мастьКод
Код Хмм... :) Код
Теперь если заменить int на Point у которого есть оператор == то всё получится) Вы явно превзошли др фанов STL. У них ракообразные конструкции хоть экономят пару строчек (иногда). У Вас наоборот, увеличивают, + вкупе с линейным перебором. Видимо, это неважно, главное - побольше template, итераторов и вообще - полной абстракции. :)Оператор == для такого объекта, как точка логично определить так: Код
Цитировать Код
Название: Re: Преждевременный вызов деструктора Отправлено: Igors от Март 14, 2012, 14:25 Да и что? Это не то что ожидается при нормальном операторе == (x == c.x && y == c.y). Напр удалить повторы из такого сортированного массива мы не сможемНазвание: Re: Преждевременный вызов деструктора Отправлено: BRE от Март 14, 2012, 14:27 Наверное, еще лучше так: :)
Код
Название: Re: Преждевременный вызов деструктора Отправлено: BRE от Март 14, 2012, 14:29 Напр удалить повторы из такого сортированного массива мы не сможем Почему? ;DКакое отношение имеет оператор < к операции удаления повторов? Название: Re: Преждевременный вызов деструктора Отправлено: m_ax от Март 14, 2012, 14:31 Наверное, еще лучше так: :) Код
;D Название: Re: Преждевременный вызов деструктора Отправлено: Igors от Март 14, 2012, 14:37 Код: // или так: Не понял, почему это его нельзя разыменовывать? end - итератор на элемент которого может и не быть. А если у Вас end нечто другое - тем хуже для Вас, такую стойкую ассоциацию менять не нужноНазвание: Re: Преждевременный вызов деструктора Отправлено: m_ax от Март 14, 2012, 14:43 Код: // или так: Не понял, почему это его нельзя разыменовывать? end - итератор на элемент которого может и не быть. А если у Вас end нечто другое - тем хуже для Вас, такую стойкую ассоциацию менять не нужноДа, транзитивность нарушается, но это не трагедия. (Во всяком случае, если не водить ещё и операторы < >) end - итератор на элемент который в данной реализации всегда есть. (end это фактически result) Код
Название: Re: Преждевременный вызов деструктора Отправлено: Igors от Март 14, 2012, 15:02 Почему? ;D Во многих случаях мы рассчитываем что в сортированном массиве одинаковые элементы (для которых == вернет true) идут подряд. Зачем же определять такой < при котором это не так?Какое отношение имеет оператор < к операции удаления повторов? Что-то Вы уж очень издалека заходите :) Название: Re: Преждевременный вызов деструктора Отправлено: BRE от Март 14, 2012, 15:05 Во многих случаях мы рассчитываем что в сортированном массиве одинаковые элементы (для которых == вернет true) идут подряд. Зачем же определять такой < при котором это не так? А разве при использовании моего оператора < для сортировки, это условиеЦитировать одинаковые элементы (для которых == вернет true) идут подряд не будет выполняться?Название: Re: Преждевременный вызов деструктора Отправлено: Igors от Март 14, 2012, 15:15 Нет, оператор == сортировке до лампочки
Название: Re: Преждевременный вызов деструктора Отправлено: BRE от Март 14, 2012, 15:31 Нет, оператор == сортировке до лампочки Эээ, а при использовании твоего оператора это измениться?Название: Re: Преждевременный вызов деструктора Отправлено: Igors от Март 14, 2012, 15:37 Эээ, а при использовании твоего оператора это измениться? Да, он в масть с == типа (a < b == c < d). Давайте с этим закругляться, неудобно занимать так много места Название: Re: Преждевременный вызов деструктора Отправлено: BRE от Март 14, 2012, 15:45 Да, он в масть с == типа (a < b == c < d). Давайте с этим закругляться, неудобно занимать так много места Ну раз в масть, то конечно, жаль математика об этом ничего не знает. |