![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
_hunter |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 8564 Регистрация: 24.6.2003 Где: Europe::Ukraine:: Kiev Репутация: 16 Всего: 98 |
Как проверить существование объекта?
( в Delphi была функция assigned() ) Заранее спасибо за ответ. -------------------- Tempora mutantur, et nos mutamur in illis... |
|||
|
||||
shedon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1209 Регистрация: 17.1.2003 Где: Нижнiй Новгородъ Репутация: 4 Всего: 11 |
можно и так: ASSERT_VALID(pOb)
-------------------- Programming is like sex: One mistake and you have to support it your lifetime |
|||
|
||||
Alexander777 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 18 Регистрация: 31.12.2006 Репутация: нет Всего: нет |
Но ASSERT_VALID прерывает выполнение программы и выдаёт сообщение. А как проверить существование объекта без прерывания программы?
|
|||
|
||||
Daevaorn |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2155 Регистрация: 29.11.2004 Где: Москва Репутация: 51 Всего: 70 |
Какого именно объекта? Объект на стеке:
В динамической памяти сложнее. Можно определить сразу после создания
в С++ и Delphi "разные" объекты. В Delphi все объекты(инстансы класса) ссылки, поэтому там и есть эта функция. |
||||||
|
|||||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
В общем случае - никак.
Можно попробовать завести в объекте спец. поле, заполнять его спец. значением, а на деструкторе чистить, и надяться, что "случайно" в этой памяти нужное значение не окажется. Но всегда есть риск, обратившись к освобожденной памяти, получить исключение. Опять же, это вовсе не обязательно. Если знать такое критически необходимо, нужно, чтобы объекты (конкретного класса или ветви иерархии) сами себя регистрировали. Например:
Что-то типа этого. Добавлено через 2 минуты и 58 секунд Естественно, регистрировать себя дожны все конструкторы, включая конструктор копирования (если нужен). Т.е. никаких генерируемых компилятором конструкторов. Кроме того, реестр лучше сделать не статиком, а синглетоном, чтобы не зависеть от момента его инициализации. -------------------- ... |
|||
|
||||
Ken |
|
|||
Новичок Профиль Группа: Участник Сообщений: 47 Регистрация: 31.3.2007 Репутация: 2 Всего: 4 |
Кажется assigned () в делфи просто проверяет является ли указатель не-nil или нет. То же самое вы можете делать в С++, если при удалении всегда будете присвоить 0 на указатель. Более элегантное решение: умные указатели.
|
|||
|
||||
HappyLife |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 642 Регистрация: 17.5.2006 Репутация: 3 Всего: 8 |
Хотел сказать тоже самое.
Присвайивайте при объявление указателя, нуль и при удалении нуль. |
|||
|
||||
Rockie |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1143 Регистрация: 23.4.2006 Репутация: 8 Всего: 31 |
+1 Добавлено через 1 минуту и 34 секунды Ken, +1 ![]() -------------------- Чтобы иметь большой гардероб - надо иметь большой гардероб. |
|||
|
||||
Любитель |
|
|||
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Собсно дельфи это делает. Сброс в nil идёт на уровне компилера. Правда это верно для объектов, а вот для произвольных динамических данных - отнюдь нет.
|
|||
|
||||
Ken |
|
||||||
Новичок Профиль Группа: Участник Сообщений: 47 Регистрация: 31.3.2007 Репутация: 2 Всего: 4 |
Вы можете легко релизовать такое поведение в С++, например через макросы:
Тогда для удаления объекта можете написать:
Макропроцессор будет генерировать:
И assigned будет работать как в дельфи. Это сообщение отредактировал(а) Ken - 28.4.2007, 17:57 |
||||||
|
|||||||
mr.Anderson |
|
|||
![]() iOS Lead Developer ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3374 Регистрация: 20.12.2004 Где: далеко Репутация: нет Всего: 128 |
|
|||
|
||||
Daevaorn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2155 Регистрация: 29.11.2004 Где: Москва Репутация: 51 Всего: 70 |
mr.Anderson, уверен?
|
|||
|
||||
JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
В этом коде не выполнится никогда. См. посты выше. Объект на стеке всегда существует до времени выхода из области видимости. |
|||
|
||||
Любитель |
|
|||
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Да не то что не выполнится - скорее всего и не скомпилится. Если мы сравнение/приведение не перегружали.
|
|||
|
||||
Xenon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1529 Регистрация: 12.4.2006 Репутация: 11 Всего: 50 |
И такой код тоже не годится? Тут, по идее, всегда будет выполнятся условие?
|
|||
|
||||
JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
||||
|
||||
Любитель |
|
|||
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Xenon, тоже не скомпилится. Из " = new myObj" => myObj - это класс. Проверять класс на нулёвость - подозрительно.
А суть в том, что если в плюсах мы что-то явно не инициализировали, то его значение неизвестно (если сие - не объект - для него есть конструктор). Указатель не исключение. Он может быть ненулевым, но эта область памяти будет недоступна. Это приведёт к вылету приложения (юзанье этой памяти). На некоторых компилерах возможен экзепшен, но это платформо- и компилеро- зависимо. |
|||
|
||||
Xenon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1529 Регистрация: 12.4.2006 Репутация: 11 Всего: 50 |
Тьфу, пардон, я имел ввиду
Error нам никогда не скажут? copy-paste делать не умею ![]() Это сообщение отредактировал(а) Xenon - 28.4.2007, 18:23 |
|||
|
||||
JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
Не-а. Иначе было бы так просто следить за динамической памятью... ![]() |
|||
|
||||
Любитель |
|
|||
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Если выделение удалось - нет (точно), если нет, то вообще говоря будет выброшен экзепшен (по стандарту). На практике - тоже компилерозависимо (читаем Саттера по этому поводу).
|
|||
|
||||
Sartorius |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1568 Регистрация: 18.7.2006 Где: Ivory tower Репутация: 8 Всего: 37 |
можно - тогда эксепшона не будет и гарантирован Null при неудаче ![]() |
|||
|
||||
Любитель |
|
|||
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
1. Я говорил конкретно про представленный код.
2. Тоже нет. Здесь я говорю не от себя (у меня нехватки памяти почему-то никогда не было :( ), но вроде как не все оси могу сие на самом деле гарантировать. На память не скажу (боюсь ошибиться), но что-то по этому поводу в "Новые сложные задачи на C++" было. |
|||
|
||||
JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
||||
|
||||
Xenon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1529 Регистрация: 12.4.2006 Репутация: 11 Всего: 50 |
JackYF, В смысле "не обязан"? Он это вообще делает, но при сбое не делает?
Вообще вроде как бы по стандарту деструктор объектов не должен вызывать исключения, поэтому сбоя при удалении мы не должны заметить, поэтому если delete обнуляет, то обнулить он должен в любом случае? Добавлено @ 18:38 Любитель, а что где это у Саттера написано? В 101 правиле или в какой-то из Сложных Задач? Это сообщение отредактировал(а) Xenon - 28.4.2007, 18:40 |
|||
|
||||
Mayk |
|
||||||||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
Было сказано забить на проверку выделения памяти. Саттер указавал на то, что даже если new/malloc завершился с успехом, это вовсе не означает что память была действительно выделена. В частности указывалось на
Добавлено @ 19:18
Новые 40 задач. задача 23-часть 2
Это сообщение отредактировал(а) Mayk - 28.4.2007, 19:20 -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
||||||||
|
|||||||||
Xenon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1529 Регистрация: 12.4.2006 Репутация: 11 Всего: 50 |
Mayk, а что есть выход? ловить bad_alloc?
|
|||
|
||||
Daevaorn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2155 Регистрация: 29.11.2004 Где: Москва Репутация: 51 Всего: 70 |
||||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Да уж, если не найдется памяти для маленького объекта, то можно спокойно рушить приложение: вряд ли уже что-то удастся спасти, если такие дела пошли... Это конечно если приложение - не какой-нибудь там кардио-стимулятор... Так их и писать по другому надо... А "большие" куски памяти лучше выделять не в куче, а прямыми системными вызовами, скажем, в Виндоус - через VirtualAlloc, и проверять, конечно. -------------------- ... |
|||
|
||||
JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
Хм... и часто ты такое делала? Не многовато издержек будет на такие вот дела? Или оборачивать еще в оберточки... |
|||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Всегда, когда большие куски нужны. Еще и с возможным использованием файл-маппинга, если совсем большая память нужна (под какой-нибудь мега-растр). Естественно, с обертками, которые генерируют исключение, и подальше от клиентского кода. Каких издержек? Это самый что ни есть прямой системный вызов: хип в конце концов тоже так выделяется. Единственные издержки - округление на размер страницы, но при выделяемых размерах - это мелочь. -------------------- ... |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |