Нужно ли использовать dynamic_cast при вызове функции, которая принимает базовый класс?

StackOverflow https://stackoverflow.com/questions/1613706

  •  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 ++. ;)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top