Ну дают админы...
От: IT Россия linq2db.com
Дата: 26.04.01 01:40
Оценка:
... десять минут назад этого форума ещё не было :o)

Ok, тогда вопрос, давно хотел спросить.
Кто из почтенной публики использует операторы *_cast, кроме dynamic_cast (без него иногда не обойтись), в реальных проектах? И зачем?

Happy coding,
Игорь.
Если нам не помогут, то мы тоже никого не пощадим.
Re: Ну дают админы...
От: mit  
Дата: 26.04.01 04:45
Оценка:
Здравствуйте IT, 25.04.2001 19:40:19 вы писали:

>Кто из почтенной публики использует операторы *_cast, кроме dynamic_cast (без него иногда не обойтись), в реальных проектах? И зачем?

>
>Happy coding,
>Игорь.

Я как-то раз использовал. Зачем? Моча в голову стукнула.
Re: Ну дают админы...
От: willi  
Дата: 26.04.01 06:46
Оценка:
Здравствуйте IT, 25.04.2001 19:40:19 вы писали:

>Кто из почтенной публики использует операторы *_cast,

>кроме dynamic_cast (без него иногда не обойтись), в
>реальных проектах? И зачем?

Я стараюсь вообще перейти именно на такие способы приведения
типа поскольку они безопаснее.
О них очень хорошо написано в книге Scott Meyers "More Effective C++"
(к сожалинию потерял ссылочку на онлайновый вариант, может кто подскажет?)
Он в своей книге страшно нахваливает эти способы преобразования типов, приводя уйму доводов "за".
Например:
— использование static_cast предохраняет тебя от изменения const переменной
— использование static_cast предохраняет тебя от несовместимого приведения типа указателя
— используя const_cast и reinterpret_cast ты явно указывешь что в этом месте ты выходишь
за установленные рамки, что делает текст программы более понятным.

в общем советую почитать эту книжечку и решить самому, нужно тебе это или нет.
\/\/i||i
Re: Ну дают админы...
От: Apple Россия  
Дата: 26.04.01 06:46
Оценка:
Здравствуйте IT, 25.04.2001 19:40:19 вы писали:

>... десять минут назад этого форума ещё не было :o)

>
>Ok, тогда вопрос, давно хотел спросить.
>Кто из почтенной публики использует операторы *_cast, кроме dynamic_cast (без него иногда не обойтись), в реальных проектах? И зачем?
>
>Happy coding,
>Игорь.

Цитата из Bjarne Stroustrup:
"C++ унаследовал от С форму записи (T)e, означающую любое преобразование, которое может быть выражено комбинацией static_cast, reinterpret_cast, const_cast, для получения значетия типа T из выражения e. Такой стиль намного опаснее, чем именованные операторы преобразования, потому что преведенную форму записи сложнее отслеживать в большой программе и вид преобразования, который имел ввиду программист не очевиден."

Надеюсь он ответил на твой вопрос :-)
Re: Ну дают админы...
От: igor_soukhov  
Дата: 26.04.01 07:56
Оценка:
Здравствуйте IT, 25.04.2001 19:40:19 вы писали:

>... десять минут назад этого форума ещё не было :o)

просто звери ;)

>Ok, тогда вопрос, давно хотел спросить.

>Кто из почтенной публики использует операторы *_cast, кроме dynamic_cast (без него иногда не обойтись), в реальных проектах? И зачем?
const_cast пришлось пару раз поюзать — функция хотела указатель не на константу (в обоих случаях я был уверен что в этой памяти (с которой сняли константность) ничего не будет изменятся ...

ну а reinterpret_cast & static_cast — они-ж как братья — если не один то другой ...

а dynamic_cast<> — это наша обсчая Ж...
(ксати буквально седня столкнулся с проблемой в VC6 — у мя есть иерархия высотой 3-4 класса — наследование от темплейтных классов (и не только) — но наследование одиночное) — и
dynamic_cast — не смог мне откастить (получал NULL pointer) — а (T*) преобразование помогло ... что под указателем лежит нунжый обект — 100% (во первых так оно и есть вот вторых виртуалтные метобы вызываются прально).



Igor
* thriving in a production environment *
Re[2]: Ну дают админы...
От: igor_soukhov  
Дата: 26.04.01 08:30
Оценка:
>dynamic_cast — не смог мне откастить (получал NULL pointer) — а (T*) преобразование помогло ... следует читать как
dynamic_cast — не смог мне откастить (получал NULL pointer) — а reinterpret_cast помог ...

;)))

Igor
* thriving in a production environment *
Re[3]: Ну дают админы...
От: IT Россия linq2db.com
Дата: 26.04.01 09:59
Оценка:
Здравствуйте igor_soukhov, 26.04.2001 02:30:36 вы писали:

>>dynamic_cast — не смог мне откастить (получал NULL pointer) — а (T*) преобразование помогло ... следует читать как

>dynamic_cast — не смог мне откастить (получал NULL pointer) — а reinterpret_cast помог ...
>

А почему это? Может ты RTTI забыл включить?
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Ну дают админы...
От: igor_soukhov  
Дата: 26.04.01 12:03
Оценка:
>Здравствуйте igor_soukhov, 26.04.2001 02:30:36 вы писали:

>>>dynamic_cast — не смог мне откастить (получал NULL pointer) — а (T*) преобразование помогло ... следует читать как

>>dynamic_cast — не смог мне откастить (получал NULL pointer) — а reinterpret_cast помог ...
>>

>А почему это? Может ты RTTI забыл включить?

Вот будет свободное время (или падать на этом месте ;) — попробую разобраться ...
А RTTI конечно включено — всетаки приходится пользовать dcast иногда ...

Igor
* thriving in a production environment *
Re[2]: Ну дают админы...
От: AndrewMiliy  
Дата: 26.04.01 12:05
Оценка:
Здравствуйте igor_soukhov, 26.04.2001 01:56:36 вы писали:

>(ксати буквально седня столкнулся с проблемой в VC6 — у мя есть иерархия высотой 3-4 класса — наследование от темплейтных классов (и не только) — но наследование одиночное) — и

>dynamic_cast — не смог мне откастить (получал NULL pointer) — а (T*) преобразование помогло ... что под указателем лежит нунжый обект — 100% (во первых так оно и есть вот вторых виртуалтные метобы вызываются прально).

Скорее всего ты пытался привести dynamic_cast'ом указатель к классу не имеющему ниодной виртуальной функции при выключеной в опциях проекта RTTI.

С наилучшими,
Андрей.
Re[3]: Ну дают админы...
От: igor_soukhov  
Дата: 26.04.01 13:59
Оценка:
Привет Андрей,

>>(ксати буквально седня столкнулся с проблемой в VC6 — у мя есть иерархия высотой 3-4 класса — наследование от темплейтных классов (и не только) — но наследование одиночное) — и

>>dynamic_cast — не смог мне откастить (получал NULL pointer) — а (T*) преобразование помогло ... что под указателем лежит нунжый обект — 100% (во первых так оно и есть вот вторых виртуалтные метобы вызываются прально).

>Скорее всего ты пытался привести dynamic_cast'ом указатель к классу не имеющему ниодной виртуальной

функции при выключеной в опциях проекта RTTI.
во первых я писал что ВИРТУАЛЬНЫЕ методы работают ! :)
во вторых — то что ты описал — проверяется в complile-time ... то есть просто бы не скомпилилось...
завтра нарисую иерархию наследования — может че проясним ...

>С наилучшими,

>Андрей.

Пасиба,
Igor
* thriving in a production environment *
Re[4]: Ну дают админы...
От: igor_soukhov  
Дата: 27.04.01 09:11
Оценка:
Здравствуйте igor_soukhov, 26.04.2001 07:59:47 вы писали:

Hi !


В общем я был неправ ... ;(

иерархия классов такова

СSnapInItem(ATL)
^
|
CSnapInItemImpl<T> : public СSnapInItem
^
|
CXXXData<T> : public CSnapInItemImpl<T>
^
|
CResultNode<T> :public CXXXData<T>
^
|
CResultNodeNum<T> : public CResultNode<T>
^
|
CConcreteResultNode : CResultNodeNum<CConcreteResultNode>


указатель p — указывает на обект CConcreteResultNode...
статический тип указателя p — CSnapInItem .... я его хочу привести к
СResultNode<CConcreteResultNode>... В СResultNode есть v-метод, кооторый
мне надо вызвавть(этот метод переопределяется в CConcreteResultNode).

в это приведения я делал из metoda другого темплейтного класса ...
код там был такой:
СResultNode<T> *pConcrecteResultNode = dynamic_cast<СResultNode<T> >(p);

естественно что T в этом методе — это не CConcreteResultNode посему и был облом ...

Best regards,
Igor



>Привет Андрей,

>
>>>(ксати буквально седня столкнулся с проблемой в VC6 — у мя есть иерархия высотой 3-4 класса — наследование от темплейтных классов (и не только) — но наследование одиночное) — и
>>>dynamic_cast — не смог мне откастить (получал NULL pointer) — а (T*) преобразование помогло ... что под указателем лежит нунжый обект — 100% (во первых так оно и есть вот вторых виртуалтные метобы вызываются прально).
>
>>Скорее всего ты пытался привести dynamic_cast'ом указатель к классу не имеющему ниодной виртуальной
>функции при выключеной в опциях проекта RTTI.
>во первых я писал что ВИРТУАЛЬНЫЕ методы работают ! :)
>во вторых — то что ты описал — проверяется в complile-time ... то есть просто бы не скомпилилось...
>завтра нарисую иерархию наследования — может че проясним ...
>
>>С наилучшими,
>>Андрей.
>
>Пасиба,
>Igor
* thriving in a production environment *
Re[5]: Ну дают админы...
От: ILYA_Varchev  
Дата: 27.04.01 14:13
Оценка:
>указатель p — указывает на обект CConcreteResultNode...
>статический тип указателя p — CSnapInItem .... я его хочу привести к
>СResultNode<CConcreteResultNode>... В СResultNode есть v-метод, кооторый
>мне надо вызвавть(этот метод переопределяется в CConcreteResultNode).
>
>в это приведения я делал из metoda другого темплейтного класса ...
>код там был такой:
>СResultNode<T> *pConcrecteResultNode = dynamic_cast<СResultNode<T> >(p);
>
>естественно что T в этом методе — это не CConcreteResultNode посему и был облом ...
>
>Best regards,
>Igor
>
вместо СResultNode<T> *pConcrecteResultNode = dynamic_cast<СResultNode<T> >(p);
не пробовал использовать
СResultNode<T> *pConcrecteResultNode = dynamic_cast<СResultNode<T>* >(p);

может поможет.
Re[6]: Ну дают админы...
От: igor_soukhov  
Дата: 27.04.01 16:12
Оценка:
Здравствуйте ILYA_Varchev, 27.04.2001 08:13:50 вы писали:

>>указатель p — указывает на обект CConcreteResultNode...

>>статический тип указателя p — CSnapInItem .... я его хочу привести к
>>СResultNode<CConcreteResultNode>... В СResultNode есть v-метод, кооторый
>>мне надо вызвавть(этот метод переопределяется в CConcreteResultNode).
>>
>>в это приведения я делал из metoda другого темплейтного класса ...
>>код там был такой:
>>СResultNode<T> *pConcrecteResultNode = dynamic_cast<СResultNode<T> >(p);
>>
>>естественно что T в этом методе — это не CConcreteResultNode посему и был облом ...
>>
>>Best regards,
>>Igor
>>
>вместо СResultNode<T> *pConcrecteResultNode = dynamic_cast<СResultNode<T> >(p);
>не пробовал использовать
>СResultNode<T> *pConcrecteResultNode = dynamic_cast<СResultNode<T>* >(p);
>
>может поможет.
это очепятка была ;)

Igor
* thriving in a production environment *
Re[7]: Ну дают админы...
От: ILYA_Varchev  
Дата: 27.04.01 17:43
Оценка:
Здравствуйте igor_soukhov, 27.04.2001 10:12:11 вы писали:

>Здравствуйте ILYA_Varchev, 27.04.2001 08:13:50 вы писали:

>
>>>указатель p — указывает на обект CConcreteResultNode...
>>>статический тип указателя p — CSnapInItem .... я его хочу привести к
>>>СResultNode<CConcreteResultNode>... В СResultNode есть v-метод, кооторый
>>>мне надо вызвавть(этот метод переопределяется в CConcreteResultNode).
>>>
>>>в это приведения я делал из metoda другого темплейтного класса ...
>>>код там был такой:
>>>СResultNode<T> *pConcrecteResultNode = dynamic_cast<СResultNode<T> >(p);
>>>
>>>естественно что T в этом методе — это не CConcreteResultNode посему и был облом ...
>>>
>>>Best regards,
>>>Igor
>>>
>>вместо СResultNode<T> *pConcrecteResultNode = dynamic_cast<СResultNode<T> >(p);
>>не пробовал использовать
>>СResultNode<T> *pConcrecteResultNode = dynamic_cast<СResultNode<T>* >(p);
>>
>>может поможет.
>это очепятка была ;)
>
>Igor
>

dyn_cast совершенно правильно работает — например СResultNode<T1> и СResultNode<T2> совершенно разные типы и dynamic_cast выдаст NULL при попыке преобразовать один тип к другому. Однако код вида:

СResultNode<T2> *p2;
.....
СResultNode<T1> *p1 = ( СResultNode<T1>*) p2;
p1 ->Method1(...);
p1 ->Method2(...);

будет, ВОЗМОЖНО, работать правильно, пока ты не будешь использовать переменные-члены класса
СResultNode<T2>.
Похожий код я встречал в MFC. Я думаю, что все знают класс CListView и у него функцию GetListCtrl()...Так вот эта функция реализована вот так:
CListCtrl& CListView::GetListCtrl()
{
return *( ( CListCtrl* ) this );
}
почему это работает? Да потому что у CListCtrl НЕТ ДАННЫХ. Всё что нужно CListCtrl — это CWnd::m_hWnd. А эта переменная определана у общего родителя — CWnd; именно поэтому всё и работает.

Возможно нечто подобное происходит и у тебя в коде :=)

Успехов!
Re[5]: Ну дают админы...
От: av Россия  
Дата: 27.04.01 18:21
Оценка:
>>>dynamic_cast — не смог мне откастить (получал NULL pointer) — а reinterpret_cast помог ...

Ну дык значит преобразование невозможно (или невозможно напрямую). reinterpret_cast — это "дубовое преобразование", типа размеры совпадают — и все. dynamic_cast, по-моему, выполняет только upcasting и downcasting, то есть невозможно преобразовать один тип к другому, если они оба порождены от одного класса, но ни один из них не является потомком другого — тогда преобразовывай сперва к общему предку, а потом — к нужному.

А reinterpret_cast тебя спасет, только за последствия не отвечаю.
Re[8]: Ну дают админы...
От: igor_soukhov  
Дата: 27.04.01 18:48
Оценка:
Здравствуйте ILYA_Varchev, 27.04.2001 11:43:07 вы писали:

>>>>указатель p — указывает на обект CConcreteResultNode...

>>>>статический тип указателя p — CSnapInItem .... я его хочу привести к
>>>>СResultNode<CConcreteResultNode>... В СResultNode есть v-метод, кооторый
>>>>мне надо вызвавть(этот метод переопределяется в CConcreteResultNode).
>>>>
>>>>в это приведения я делал из metoda другого темплейтного класса ...
>>>>код там был такой:
>>>>СResultNode<T> *pConcrecteResultNode = dynamic_cast<СResultNode<T> >(p);
>>>>
>>>>естественно что T в этом методе — это не CConcreteResultNode посему и был облом ...
>>>>
>>>>Best regards,
>>>>Igor
>>>>
>>>вместо СResultNode<T> *pConcrecteResultNode = dynamic_cast<СResultNode<T> >(p);
>>>не пробовал использовать
>>>СResultNode<T> *pConcrecteResultNode = dynamic_cast<СResultNode<T>* >(p);
>>>
>>>может поможет.
>>это очепятка была ;)
>>
>>Igor
>>
>
>dyn_cast совершенно правильно работает — например СResultNode<T1> и СResultNode<T2> совершенно разные типы и dynamic_cast выдаст NULL при попыке преобразовать один тип к другому. Однако код вида:

СResultNode<CConcreteResultNode> это базовый класс для моего CConcreteResultNode... к
нему я и пытался привести... (проблема была в том что этот кастинг проводился был в методе
СОВСЕМ другого ТЕМПЛЕЙТНОГО класса (и T там обозначало не CConcreteResultNode) ...

>СResultNode<T2> *p2;

>.....
>СResultNode<T1> *p1 = ( СResultNode<T1>*) p2;
>p1 ->Method1(...);
>p1 ->Method2(...);
>
>будет, ВОЗМОЖНО, работать правильно, пока ты не будешь использовать переменные-члены класса
>СResultNode<T2>.
>Похожий код я встречал в MFC. Я думаю, что все знают класс CListView и у него функцию GetListCtrl()...Так вот эта функция реализована вот так:
>CListCtrl& CListView::GetListCtrl()
>{
> return *( ( CListCtrl* ) this );
>}
>почему это работает? Да потому что у CListCtrl НЕТ ДАННЫХ. Всё что нужно CListCtrl — это CWnd::m_hWnd. А эта переменная определана у общего родителя — CWnd; именно поэтому всё и работает.
>
>Возможно нечто подобное происходит и у тебя в коде :=)
возможно ...

>Успехов!

Пасиба,
Igor
* thriving in a production environment *
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.