dynamic_cast и множественное наследование
От: Владик Россия  
Дата: 05.09.05 14:36
Оценка:
Привет!

Что говорит стандарт по поводу dynamic_cast к классу, отнаследованному больше одного раза?

struct D {};
struct D1 : D {};
struct D2 : D {};
struct Base {};
struct X : Base, D1, D2 {}
...
dynamic_cast<D *>(pointer_to_Base);


Вопрос скорее академический (ибо является следствием кривого дизайна), но все равно интересно

P.S. Похоже мой компилятор в такой ситуации берет первый попавшийся D.
Как все запущенно...
Re: dynamic_cast и множественное наследование
От: _DAle_ Беларусь  
Дата: 05.09.05 14:54
Оценка: 3 (2)
Здравствуйте, Владик, Вы писали:

В>Привет!


В>Что говорит стандарт по поводу dynamic_cast к классу, отнаследованному больше одного раза?


В>
В>struct D {};
В>struct D1 : D {};
В>struct D2 : D {};
В>struct Base {};
В>struct X : Base, D1, D2 {}
В>...
В>dynamic_cast<D *>(pointer_to_Base);
В>


В>Вопрос скорее академический (ибо является следствием кривого дизайна), но все равно интересно


В>P.S. Похоже мой компилятор в такой ситуации берет первый попавшийся D.


Ну я так понимаю, что из этого
5.2.7/8

The run-time check logically executes as follows:
— If, in the most derived object pointed (referred) to by v, v points (refers) to a public base class subobject of a T object, and if only one object of type T is derived from the sub-object pointed (referred) to by v, the result is a pointer (an lvalue referring) to that T object.
— Otherwise, if v points (refers) to a public base class sub-object of the most derived object, and the type of the most derived object has a base class, of type T, that is unambiguous and public, the result is a pointer (an lvalue referring) to the T sub-object of the most derived object.
— Otherwise, the run-time check fails.

The value of a failed cast to pointer type is the null pointer value of the required result type. A failed cast to reference type throws bad_cast (18.5.2).

и следующего за этим примера следует, что результатом dynamic_cast должно быть null pointer value.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re: dynamic_cast и множественное наследование
От: 0xDEADBEEF Ниоткуда  
Дата: 05.09.05 15:00
Оценка: 2 (1)
Здравствуйте, Владик, Вы писали:

В>Привет!


В>Что говорит стандарт по поводу dynamic_cast к классу, отнаследованному больше одного раза?


В>
В>struct D {};
В>struct D1 : D {};
В>struct D2 : D {};
В>struct Base {};
В>struct X : Base, D1, D2 {}
В>...
В>dynamic_cast<D *>(pointer_to_Base);
В>


В>Вопрос скорее академический (ибо является следствием кривого дизайна), но все равно интересно

Ну, во-первых, для того чтобы dynamic_cast работал, все базовые классы должны быть полиморфными (т.е иметь виртуальные функции).
И, во вторых, D должен быть "accessible unambiguous base class". Насчет "accessible" все ОК, а вот насчет "unambiguous", проблемы.

Так что, твой dynamic_cast должен возвращать NULL.

В>P.S. Похоже мой компилятор в такой ситуации берет первый попавшийся D.

Какой-то странный у тебя компилятор. Все компилятоы что есть у меня (VC 7.1, 6.0, gcc 3.4.5) возвращают что надо.
__________
16.There is no cause so right that one cannot find a fool following it.
Re: dynamic_cast и множественное наследование
От: Павел Кузнецов  
Дата: 05.09.05 15:46
Оценка: 2 (1)
Владик,

> Что говорит стандарт по поводу dynamic_cast к классу, отнаследованному больше одного раза?


Говорит, что это зависит от того, какая схема наследования, и как именно производится dynamic_cast (5.2.7/8-9).

В случае, приведенном ниже (при условии добавления виртуальных функций), стандарт говорит "run-time check fails", что для dynamic_cast<T*> приводит к возврату 0, а для dynamic_cast<T&> -- к исключению.

>
> struct D {};
> struct D1 : D {};
> struct D2 : D {};
> struct Base {};
> struct X : Base, D1, D2 {}
> ...
> dynamic_cast<D *>(pointer_to_Base);
>


А вот если бы D были унаследованы от Base, то результатом был бы тот подобъект D, который унаследован от подобъекта Base, указатель на который был передан в качестве аргумента dynamic_cast:
#include <iostream>

struct Base { virtual ~Base() { } };
struct D : Base { virtual ~D() { } };
struct D1 : D {};
struct D2 : D {};
struct X : D1, D2 {};

int main()
{
   X x;
   Base* pointer_to_Base = static_cast<D1*>(&x);
   std::cout << dynamic_cast<D*>(pointer_to_Base);
}

здесь должен быть напечатан адрес подобъекта D, входящего в подобъект D1.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.