C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Указатель на объект., Живой или мертвый?
klen
Отправлено: 27.03.2004, 11:17


Машинист паровоза

Группа: Участник
Сообщений: 239



Здравствуйте все.
Подскажите пожалуйста, как имея указатель TComponent* (не равный нулю) определить жив ли еще объект на который он указывает или его уже разрушили оператором delete.
Есть вариант вызвать любую нестатическую функцию класса, это приведет к исключению в случаее если он мертвый, но не хочется через исключения это делать.
Георгий
Отправлено: 27.03.2004, 12:13


Почетный железнодорожник

Группа: Модератор
Сообщений: 874



попробуй использовать умные указатели (smart pointers) — в BCB класс называется auto_ptr
klen
Отправлено: 27.03.2004, 15:09


Машинист паровоза

Группа: Участник
Сообщений: 239



Век живи век учись, первый раз от таком слышу.
Прикольно, даже хелп есть.
Спасибо.
Asher
Отправлено: 29.03.2004, 08:34


Мастер участка

Группа: Модератор
Сообщений: 550



Привет.
Ты с auto_ptr будь по-аккуратнее. Они там "прикольно" копируются, особенное если не дай бог это указатель приведенный к предку. wink.gif
Потеря информации гарантированна. Именно по этой причине с ними категорически нельзя испльзовать STL'евские контейнеры.
olegenty
Отправлено: 29.03.2004, 10:56


Ветеран

Группа: Модератор
Сообщений: 2412



если уверен в том, что по указателю был экземпляр вполне конкретного класса, то можешь сделать следующее:
[CODE]
if (ТвойКласс *test = dynamic_cast<ТвойКласс*>(ТвойУказатель))
{
делай, всё, что хочешь...;
} else
{
raise Exception("Указатель успешно скончался/The pointer is succesfully dead");
}
Deem
Отправлено: 29.03.2004, 14:59


Мастер участка

Группа: Участник
Сообщений: 327



Попробуй обратиться к методу или свойству объекта в try {}
А дальше catch(...) {Pointer = NULL;}
А вобще-то даже delete пинтер никогда не обнуляет. Следи за указателями, и обнуляй при удалении объекта. А все элементы VCL не оставляют указателей при удалении родственников (не встречал).
klen
Отправлено: 29.03.2004, 23:37


Машинист паровоза

Группа: Участник
Сообщений: 239



Мужики, по эксепшену то понятно, обьекта нет значит ошибка нарушения зашиты памяти будет, а как без эксепшенов обойтись.

Вопрос удобства на самом деле — в программе то раьотать будет, а вот пока ее пишешь замучишься на кнопки OK давит при каждом эксепшене.
Asher
Отправлено: 30.03.2004, 08:27


Мастер участка

Группа: Модератор
Сообщений: 550



Привет.
Если разрушаешь сам — то присваивай указателю NULL, а если делаешь дополнительные указатели на этот объект — то делай указатель на этот указатель. Тогда обнулив базовый указатель существование объекта можно проверить одиночным разименованием с сравнением на NULL.
Что-то типа этого smile.gif
CODE

int i1 = 10;
int *pi1;
int **ppi1;
pi1 = &i1;
ppi1 = &pi1;
*pi1 = 11;
pi1 = NULL;
if (*ppi1 != NULL)
**ppi1 = 12;

klen
Отправлено: 30.03.2004, 11:58


Машинист паровоза

Группа: Участник
Сообщений: 239



Так вся проблема в том что не я разрушаю, это принципиальная особенность моей задачи — объект разделяймый, а те кто к нему имеют доступ не должны иметь между собой никакого интерфейса. Задача такая однако
Asher
Отправлено: 30.03.2004, 12:09


Мастер участка

Группа: Модератор
Сообщений: 550



Ну дык...
Удаляется же он не просто так, а в ответ на какие-то действия. Там и обнулять самому.
А все остальные обращающиеся — имеют к нему доступ не через указатель на объект, а через указатель на указатель.
Или они имеют к нему доступ без указателя? biggrin.gif
klen
Отправлено: 30.03.2004, 12:21


Машинист паровоза

Группа: Участник
Сообщений: 239



Да вот эти самые действия в другой биьлиотек и писаной савсем не мной я мало чего переделать могу.
Ладно, хватит, переведем в другу плоскость:
Чисто академический вопрос :
Имеем значения адресса памяти 0xXXXXXXXXX , задача — установить : является ли эта ячейка памяти указателем на обьект класса насследованного от TXyz или не является таковым. Все.
olegenty
Отправлено: 30.03.2004, 13:18


Ветеран

Группа: Модератор
Сообщений: 2412



вот как раз так, как я выше писал:

CODE

if (TXyz *Test = dynamic_cast<TXyz*>(Твой адрес))
{
   ShowMessage("Является наследником TXyz");
   // продолжаетм разбор
   if (TXyzНаследник *TestНаследник = dynamic_cast<TXyzНаследник*>(Test))
   {
   ...
   }
}

Asher
Отправлено: 30.03.2004, 14:07


Мастер участка

Группа: Модератор
Сообщений: 550



Конечно. Только все прекрасно приведется, если никто память не по-портил biggrin.gif
Вставь это в пустой проект
CODE

TForm* l_pForm = new TForm(this);//
delete l_pForm;//
TForm* l_pTest = dynamic_cast<TForm*>(l_pForm);//Попытка приведения
if (l_pTest != NULL){
 int i1 = 0;//
}

Ы?
klen
Отправлено: 30.03.2004, 16:24


Машинист паровоза

Группа: Участник
Сообщений: 239



Мужики, проблема решена.

Так как по указателю нет ничего dynamic_cast обязательно к эксепшену приведет, ему RTTI обиекта нужно, а если обьекта не то, и RTTI нет со всеми вытекающими, я о об этом подробно написал http://www.bcbdev.ru/phpbb/viewtopic.php?t=1024

Проблема решается гениально и просто (по моему мнению) — Api дает функции менеджера памяти для выяснения принадлежит ли регион адресного пространства процессу или нет и если принадлежит то что с ним может желать процесс, если обьект разрушен то регион из кучи забирает система и в него нельзя ни писать ни читать ни ваполнять в нем код!

Для тех кто догнал постановку задачи и для которых она является актуальной отсылаю к справке по Memory Management Functions
смотри описание функций

IsBadCodePtr
IsBadHugeReadPtr
IsBadHugeWritePtr
IsBadReadPtr
IsBadStringPtr
IsBadWritePtr

Спасибо всем за участие.

--- может так статся что в регионен памяти уже другой объект, тогда.....---

Отредактировано klen — 30/03/2004, 17:27

Вернуться в Вопросы программирования в C++Builder