Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> существование объекта 
:(
    Опции темы
_hunter
  Дата 25.11.2003, 12:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 16
Всего: 98



Как проверить существование объекта?
( в Delphi была функция assigned() )

Заранее спасибо за ответ.


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
shedon
Дата 25.11.2003, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1209
Регистрация: 17.1.2003
Где: Нижнiй Новгородъ

Репутация: 4
Всего: 11



можно и так: ASSERT_VALID(pOb)


--------------------
Programming is like sex: One mistake and you have to support it your lifetime
PM MAIL WWW ICQ   Вверх
Alexander777
Дата 27.4.2007, 00:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 31.12.2006

Репутация: нет
Всего: нет



Но ASSERT_VALID прерывает выполнение программы и выдаёт сообщение. А как проверить существование объекта без прерывания программы?
PM MAIL   Вверх
Daevaorn
Дата 27.4.2007, 01:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(Alexander777 @  27.4.2007,  01:57 Найти цитируемый пост)
А как проверить существование объекта без прерывания программы?

Какого именно объекта?
Объект на стеке:
Код

class Foo
{
//...
};

//...
Foo bar;
//здесь уже объект существует.
 
В динамической памяти сложнее. Можно определить сразу после создания
Код

Foo* bar = new Foo;
//здесь уже объект существует.


Цитата(_hunter @  25.11.2003,  13:09 Найти цитируемый пост)
 в Delphi была функция assigned() 

в С++ и Delphi "разные" объекты. В Delphi все объекты(инстансы класса) ссылки, поэтому там и есть эта функция.
PM MAIL WWW   Вверх
Earnest
Дата 27.4.2007, 17:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



В общем случае - никак.
Можно попробовать завести в объекте спец. поле, заполнять его спец. значением, а на деструкторе чистить, и надяться, что "случайно" в этой памяти нужное значение не окажется. Но всегда есть риск, обратившись к освобожденной памяти, получить исключение. Опять же, это вовсе не обязательно.

Если знать такое критически необходимо, нужно, чтобы объекты (конкретного класса или ветви иерархии) сами себя регистрировали. Например:

Код

// объявление:
class WiseObj
{
public:
   WiseObj()   { Register (this); }
  ~WiseObj() { Unregister (this); }

   static bool IsValid (const WiseObj*);

private:
   static void Register();
   static void Unregister();
};

// реализация:
static std::set<WiseObj*> _Registry;

void WiseObj::Register (WiseObj* pObj)
{
   _Registry.insert (pObj);
}

void WiseObj::Unregister (WiseObj* pObj)
{
   _Registry.erase(pObj);
}

bool WiseObj::IsValid (const WiseObj* pObj)
{
   return _Registry.find (pObj) != _Registry.end();
}


Что-то типа этого.

Добавлено через 2 минуты и 58 секунд
Естественно, регистрировать себя дожны все конструкторы, включая конструктор копирования (если нужен). Т.е. никаких генерируемых компилятором конструкторов. Кроме того, реестр лучше сделать не статиком, а синглетоном, чтобы не зависеть от момента его инициализации.


--------------------
...
PM   Вверх
Ken
Дата 28.4.2007, 00:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 31.3.2007

Репутация: 2
Всего: 4



Кажется assigned () в делфи просто проверяет является ли указатель не-nil  или нет. То же самое вы можете делать в С++, если при удалении всегда будете присвоить 0 на указатель. Более элегантное решение: умные указатели.
PM MAIL   Вверх
HappyLife
Дата 28.4.2007, 09:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 642
Регистрация: 17.5.2006

Репутация: 3
Всего: 8



Хотел сказать тоже самое.
Присвайивайте при объявление указателя, нуль и при удалении нуль.
PM MAIL   Вверх
Rockie
Дата 28.4.2007, 14:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1143
Регистрация: 23.4.2006

Репутация: 8
Всего: 31



Цитата(HappyLife @  28.4.2007,  09:30 Найти цитируемый пост)
Присвайивайте при объявление указателя, нуль и при удалении нуль.

+1

Добавлено через 1 минуту и 34 секунды
Ken, +1 smile




--------------------
Чтобы иметь большой гардероб - надо иметь большой гардероб.
PM   Вверх
Любитель
Дата 28.4.2007, 17:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

Репутация: 24
Всего: 92



Собсно дельфи это делает. Сброс в nil идёт на уровне компилера. Правда это верно для объектов, а вот для произвольных динамических данных - отнюдь нет.


--------------------
PM MAIL ICQ Skype   Вверх
Ken
Дата 28.4.2007, 17:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 31.3.2007

Репутация: 2
Всего: 4



Вы можете легко релизовать такое поведение в С++, например через макросы: 
Код

#define assigned(ptr) (ptr == NULL)
#define deleteImproved(ptr) { delete ptr; ptr = NULL; }


Тогда для удаления объекта можете написать:
Код

deleteImproved (foo);


Макропроцессор будет генерировать:
Код

{ delete foo; foo = NULL; }


И assigned будет работать как в дельфи.

Это сообщение отредактировал(а) Ken - 28.4.2007, 17:57
PM MAIL   Вверх
mr.Anderson
Дата 28.4.2007, 17:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: нет
Всего: 128



Код

class Foo {
 ...
};
//------------------------------------

Foo myObj;

...

if( myObj != NULL )
 //объект существует
else //не существует



--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
Daevaorn
Дата 28.4.2007, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



mr.Anderson, уверен?
PM MAIL WWW   Вверх
JackYF
Дата 28.4.2007, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(mr.Anderson @  28.4.2007,  17:54 Найти цитируемый пост)
if( myObj != NULL )

В этом коде не выполнится никогда. См. посты выше. Объект на стеке всегда существует до времени выхода из области видимости.



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Любитель
Дата 28.4.2007, 18:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

Репутация: 24
Всего: 92



Да не то что не выполнится - скорее всего и не скомпилится. Если мы сравнение/приведение не перегружали.


--------------------
PM MAIL ICQ Skype   Вверх
Xenon
Дата 28.4.2007, 18:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1529
Регистрация: 12.4.2006

Репутация: 11
Всего: 50



И такой код тоже не годится? Тут, по идее, всегда будет выполнятся условие?
Код

Foo* pTr;
pTr = new myObj;
if( myObj != 0 ) ...



--------------------
user posted image  
PM MAIL   Вверх
JackYF
Дата 28.4.2007, 18:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(Любитель @  28.4.2007,  18:06 Найти цитируемый пост)
скорее всего и не скомпилится.

Да, точно. Еще лучше smile



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Любитель
Дата 28.4.2007, 18:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

Репутация: 24
Всего: 92



Xenon, тоже не скомпилится. Из " = new myObj" => myObj - это класс. Проверять класс на нулёвость - подозрительно.

А суть в том, что если в плюсах мы что-то явно не инициализировали, то его значение неизвестно (если сие - не объект - для него есть конструктор). Указатель не исключение. Он может быть ненулевым, но эта область памяти будет недоступна. Это приведёт к вылету приложения (юзанье этой памяти). На некоторых компилерах возможен экзепшен, но это платформо- и компилеро- зависимо.


--------------------
PM MAIL ICQ Skype   Вверх
Xenon
Дата 28.4.2007, 18:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1529
Регистрация: 12.4.2006

Репутация: 11
Всего: 50



Тьфу, пардон, я имел ввиду
Код

Foo* pTr;
pTr = new Foo;
if( pTr == 0 ) std::cout << "Error";

Error нам никогда не скажут?

copy-paste делать не умею smile

Это сообщение отредактировал(а) Xenon - 28.4.2007, 18:23


--------------------
user posted image  
PM MAIL   Вверх
JackYF
Дата 28.4.2007, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(Xenon @  28.4.2007,  18:22 Найти цитируемый пост)
Error нам никогда не скажут?

Не-а. Иначе было бы так просто следить за динамической памятью...  smile 



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Любитель
Дата 28.4.2007, 18:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

Репутация: 24
Всего: 92



Если выделение удалось - нет (точно), если нет, то вообще говоря будет выброшен экзепшен (по стандарту). На практике - тоже компилерозависимо (читаем Саттера по этому поводу).


--------------------
PM MAIL ICQ Skype   Вверх
Sartorius
Дата 28.4.2007, 18:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1568
Регистрация: 18.7.2006
Где: Ivory tower

Репутация: 8
Всего: 37



Код

new(nothrow) Foo();


 можно - тогда эксепшона не будет и гарантирован Null при неудаче  smile 
PM MAIL ICQ   Вверх
Любитель
Дата 28.4.2007, 18:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

Репутация: 24
Всего: 92



1. Я говорил конкретно про представленный код.
2. 
Цитата(Sartorius @  28.4.2007,  18:31 Найти цитируемый пост)
гарантирован

Тоже нет. Здесь я говорю не от себя (у меня нехватки памяти почему-то никогда не было :( ), но вроде как не все оси могу сие на самом деле гарантировать. На память не скажу (боюсь ошибиться), но что-то по этому поводу в "Новые сложные задачи на C++" было.


--------------------
PM MAIL ICQ Skype   Вверх
JackYF
Дата 28.4.2007, 18:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(Sartorius @  28.4.2007,  18:31 Найти цитируемый пост)
можно - тогда эксепшона не будет и гарантирован Null при неудаче  smile 

Да, но это половинчатое решение.
Код

delete pTr; 


не обязан приводить указатель к 0.



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Xenon
Дата 28.4.2007, 18:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1529
Регистрация: 12.4.2006

Репутация: 11
Всего: 50



JackYF, В смысле "не обязан"? Он это вообще делает, но при сбое не делает?
Вообще вроде как бы по стандарту деструктор объектов не должен вызывать исключения, поэтому сбоя при удалении мы не должны заметить, поэтому если delete обнуляет, то обнулить он должен в любом случае?

Добавлено @ 18:38
Любитель, а что где это у Саттера написано? В 101 правиле или в какой-то из Сложных Задач?

Это сообщение отредактировал(а) Xenon - 28.4.2007, 18:40


--------------------
user posted image  
PM MAIL   Вверх
Mayk
Дата 28.4.2007, 19:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


^аВаТаР^ сообщение>>
****


Профиль
Группа: Участник
Сообщений: 2616
Регистрация: 22.5.2005
Где: за границей разум а

Репутация: 45
Всего: 134



Цитата(Любитель @  28.4.2007,  22:34 Найти цитируемый пост)
На память не скажу (боюсь ошибиться), но что-то по этому поводу в "Новые сложные задачи на C++" было.

Было сказано забить на проверку выделения памяти. Саттер указавал на то, что даже если
new/malloc завершился с успехом, это вовсе не означает что память была действительно выделена. В частности указывалось на
Цитата(man malloc)

      Linux follows an optimistic memory  allocation  strategy.   This  means
       that when malloc() returns non-NULL there is no guarantee that the mem‐
       ory really is available. In case it turns out that the system is out of
       memory,  one  or  more  processes  will  be  killed by the infamous OOM
       killer.


Добавлено @ 19:18
Цитата(Xenon @  28.4.2007,  22:37 Найти цитируемый пост)

Любитель, а что где это у Саттера написано? В 101 правиле или в какой-то из Сложных Задач?

Новые 40 задач. задача 23-часть 2

Цитата

Рекомендация. Мораль #1: избегайте использование оператора new, не генерируюшего исключения.
...
Рекомендация  Мораль #2: очень часто проверка отказа в операторе new бесполезна


Это сообщение отредактировал(а) Mayk - 28.4.2007, 19:20


--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
Xenon
Дата 28.4.2007, 19:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1529
Регистрация: 12.4.2006

Репутация: 11
Всего: 50



Mayk, а что есть выход? ловить bad_alloc?


--------------------
user posted image  
PM MAIL   Вверх
Daevaorn
Дата 28.4.2007, 19:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(Xenon @  28.4.2007,  20:31 Найти цитируемый пост)
 а что есть выход? ловить bad_alloc?

не делать ничего. смысла практически нет.
PM MAIL WWW   Вверх
Earnest
Дата 28.4.2007, 20:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Цитата(Daevaorn @  28.4.2007,  20:47 Найти цитируемый пост)
не делать ничего. смысла практически нет. 

Да уж, если не найдется памяти для маленького объекта, то можно спокойно рушить приложение: вряд ли уже что-то удастся спасти, если такие дела пошли... 
Это конечно если приложение - не какой-нибудь там кардио-стимулятор... Так их и писать по другому надо...

А "большие" куски памяти лучше выделять не в куче, а прямыми системными вызовами, скажем, в Виндоус - через VirtualAlloc,  и проверять, конечно.



--------------------
...
PM   Вверх
JackYF
Дата 29.4.2007, 23:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(Earnest @  28.4.2007,  20:02 Найти цитируемый пост)
скажем, в Виндоус - через VirtualAlloc,  и проверять, конечно.


Хм... и часто ты такое делала?
Не многовато издержек будет на такие вот дела? Или оборачивать еще в оберточки...



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Earnest
Дата 2.5.2007, 08:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Цитата(JackYF @  30.4.2007,  00:29 Найти цитируемый пост)
Хм... и часто ты такое делала?

Всегда, когда большие куски нужны. Еще и с возможным использованием файл-маппинга, если совсем большая память нужна (под какой-нибудь мега-растр). Естественно, с обертками, которые генерируют исключение, и подальше от клиентского кода.
Каких издержек? Это самый что ни есть прямой системный вызов: хип в конце концов тоже так выделяется.
Единственные издержки - округление на размер страницы, но при выделяемых размерах - это мелочь.


--------------------
...
PM   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1380 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.