Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > существование объекта |
Автор: _hunter 25.11.2003, 12:09 |
Как проверить существование объекта? ( в Delphi была функция assigned() ) Заранее спасибо за ответ. |
Автор: shedon 25.11.2003, 12:14 |
можно и так: ASSERT_VALID(pOb) |
Автор: Alexander777 27.4.2007, 00:57 |
Но ASSERT_VALID прерывает выполнение программы и выдаёт сообщение. А как проверить существование объекта без прерывания программы? |
Автор: Earnest 27.4.2007, 17:17 | ||
В общем случае - никак. Можно попробовать завести в объекте спец. поле, заполнять его спец. значением, а на деструкторе чистить, и надяться, что "случайно" в этой памяти нужное значение не окажется. Но всегда есть риск, обратившись к освобожденной памяти, получить исключение. Опять же, это вовсе не обязательно. Если знать такое критически необходимо, нужно, чтобы объекты (конкретного класса или ветви иерархии) сами себя регистрировали. Например:
Что-то типа этого. Добавлено через 2 минуты и 58 секунд Естественно, регистрировать себя дожны все конструкторы, включая конструктор копирования (если нужен). Т.е. никаких генерируемых компилятором конструкторов. Кроме того, реестр лучше сделать не статиком, а синглетоном, чтобы не зависеть от момента его инициализации. |
Автор: Ken 28.4.2007, 00:07 |
Кажется assigned () в делфи просто проверяет является ли указатель не-nil или нет. То же самое вы можете делать в С++, если при удалении всегда будете присвоить 0 на указатель. Более элегантное решение: умные указатели. |
Автор: HappyLife 28.4.2007, 09:30 |
Хотел сказать тоже самое. Присвайивайте при объявление указателя, нуль и при удалении нуль. |
Автор: Rockie 28.4.2007, 14:42 | ||
+1 Добавлено через 1 минуту и 34 секунды Ken, +1 ![]() |
Автор: Любитель 28.4.2007, 17:34 |
Собсно дельфи это делает. Сброс в nil идёт на уровне компилера. Правда это верно для объектов, а вот для произвольных динамических данных - отнюдь нет. |
Автор: Ken 28.4.2007, 17:51 | ||||||
Вы можете легко релизовать такое поведение в С++, например через макросы:
Тогда для удаления объекта можете написать:
Макропроцессор будет генерировать:
И assigned будет работать как в дельфи. |
Автор: mr.Anderson 28.4.2007, 17:54 | ||
|
Автор: Daevaorn 28.4.2007, 17:59 |
mr.Anderson, уверен? |
Автор: JackYF 28.4.2007, 17:59 |
В этом коде не выполнится никогда. См. посты выше. Объект на стеке всегда существует до времени выхода из области видимости. |
Автор: Любитель 28.4.2007, 18:06 |
Да не то что не выполнится - скорее всего и не скомпилится. Если мы сравнение/приведение не перегружали. |
Автор: Xenon 28.4.2007, 18:15 | ||
И такой код тоже не годится? Тут, по идее, всегда будет выполнятся условие?
|
Автор: JackYF 28.4.2007, 18:20 |
Да, точно. Еще лучше ![]() |
Автор: Любитель 28.4.2007, 18:21 |
Xenon, тоже не скомпилится. Из " = new myObj" => myObj - это класс. Проверять класс на нулёвость - подозрительно. А суть в том, что если в плюсах мы что-то явно не инициализировали, то его значение неизвестно (если сие - не объект - для него есть конструктор). Указатель не исключение. Он может быть ненулевым, но эта область памяти будет недоступна. Это приведёт к вылету приложения (юзанье этой памяти). На некоторых компилерах возможен экзепшен, но это платформо- и компилеро- зависимо. |
Автор: Xenon 28.4.2007, 18:22 | ||
Тьфу, пардон, я имел ввиду
Error нам никогда не скажут? copy-paste делать не умею ![]() |
Автор: JackYF 28.4.2007, 18:26 |
Не-а. Иначе было бы так просто следить за динамической памятью... ![]() |
Автор: Любитель 28.4.2007, 18:28 |
Если выделение удалось - нет (точно), если нет, то вообще говоря будет выброшен экзепшен (по стандарту). На практике - тоже компилерозависимо (читаем Саттера по этому поводу). |
Автор: Sartorius 28.4.2007, 18:31 | ||
можно - тогда эксепшона не будет и гарантирован Null при неудаче ![]() |
Автор: Любитель 28.4.2007, 18:34 |
1. Я говорил конкретно про представленный код. 2. Тоже нет. Здесь я говорю не от себя (у меня нехватки памяти почему-то никогда не было :( ), но вроде как не все оси могу сие на самом деле гарантировать. На память не скажу (боюсь ошибиться), но что-то по этому поводу в "Новые сложные задачи на C++" было. |
Автор: JackYF 28.4.2007, 18:34 | ||||
Да, но это половинчатое решение.
не обязан приводить указатель к 0. |
Автор: Xenon 28.4.2007, 18:37 |
JackYF, В смысле "не обязан"? Он это вообще делает, но при сбое не делает? Вообще вроде как бы по стандарту деструктор объектов не должен вызывать исключения, поэтому сбоя при удалении мы не должны заметить, поэтому если delete обнуляет, то обнулить он должен в любом случае? Добавлено @ 18:38 Любитель, а что где это у Саттера написано? В 101 правиле или в какой-то из Сложных Задач? |
Автор: Mayk 28.4.2007, 19:14 | ||||||||
Было сказано забить на проверку выделения памяти. Саттер указавал на то, что даже если new/malloc завершился с успехом, это вовсе не означает что память была действительно выделена. В частности указывалось на
Добавлено @ 19:18
Новые 40 задач. задача 23-часть 2
|
Автор: Xenon 28.4.2007, 19:31 |
Mayk, а что есть выход? ловить bad_alloc? |
Автор: Daevaorn 28.4.2007, 19:47 |
не делать ничего. смысла практически нет. |
Автор: Earnest 28.4.2007, 20:02 |
Да уж, если не найдется памяти для маленького объекта, то можно спокойно рушить приложение: вряд ли уже что-то удастся спасти, если такие дела пошли... Это конечно если приложение - не какой-нибудь там кардио-стимулятор... Так их и писать по другому надо... А "большие" куски памяти лучше выделять не в куче, а прямыми системными вызовами, скажем, в Виндоус - через VirtualAlloc, и проверять, конечно. |
Автор: JackYF 29.4.2007, 23:29 |
Хм... и часто ты такое делала? Не многовато издержек будет на такие вот дела? Или оборачивать еще в оберточки... |
Автор: Earnest 2.5.2007, 08:15 |
Всегда, когда большие куски нужны. Еще и с возможным использованием файл-маппинга, если совсем большая память нужна (под какой-нибудь мега-растр). Естественно, с обертками, которые генерируют исключение, и подальше от клиентского кода. Каких издержек? Это самый что ни есть прямой системный вызов: хип в конце концов тоже так выделяется. Единственные издержки - округление на размер страницы, но при выделяемых размерах - это мелочь. |