Привет!
Что говорит стандарт по поводу 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.
Здравствуйте, Владик, Вы писали:
В>Привет!
В>Что говорит стандарт по поводу 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>>
Здравствуйте, Владик, Вы писали:
В>Привет!
В>Что говорит стандарт по поводу 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) возвращают что надо.
Владик,
> Что говорит стандарт по поводу 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
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен