Нужно ли использовать dynamic_cast при вызове функции, которая принимает базовый класс?
-
06-07-2019 - |
Вопрос
У меня есть несколько классов, подобных этому:
interface class IA
{
};
interface class IB
{
};
public ref class C : public IA, public IB
{
};
public ref class D
{
void DoSomething(IA^ aaa)
{
}
void Run()
{
C^ bob = gcnew C();
DoSomething(dynamic_cast<IA^>(bob)); // #1
DoSomething(bob); // #2
}
};
В данный момент я всегда пытаюсь использовать динамическое приведение при вызове такой функции (# 1 выше).
Однако это делает код довольно уродливым, поэтому я хочу знать, действительно ли это необходимо.
Используете ли вы dynamic_cast таким образом? Если так, то какова главная причина?
Решение
Поскольку мы знаем, что bob
имеет тип C ^
, мы знаем, что во время компиляции его можно безопасно уменьшить до IA ^
, и поэтому dynamic_cast
здесь эквивалентно static_cast
. Кроме того, неявное приведение, которое вы предлагаете, также безопасно.
dynamic_cast
требуется только при переходе с базового типа на производный.
Другие советы
В стандартном C ++ вы используете dynamic_cast для перехода по иерархии, а не вверх. В этом случае вы использовали бы его, чтобы попытаться преобразовать IA или IB в C:
IA^ temp = /* get a C in some way. */;
C^ tempC = dynamic_cast<C^>(temp);
Нет, я думаю, что в C ++ / CLI вам также не нужно динамическое приведение здесь. Производное * неявно преобразуется в Base *, если нет двусмысленности w.r.t. множественное наследование. То же самое, вероятно, верно для «gc-указателей». В C ++ для динамического приведения - при трансляции - требуются полиморфные классы (по крайней мере, с одной виртуальной функцией). Я не знаю, как C ++ / CLI справляется с этим, хотя. Я думаю, что каждый класс CLI по умолчанию полиморфен.
Кстати, вы можете удалить тег C ++. ;) Р>