Проверка, может ли перекрестное приведение работать?

Я знаю, что разрешено использовать dynamic_cast для «перекрестного» бросать "через иерархию классов. Например, если у меня есть классы, которые выглядят следующим образом:

  A   B
   \ /
    C

Если у меня есть указатель A * , указывающий на объект типа C , то я могу использовать

A* aPtr = /* ... something that produces a C* ... */
B* bPtr = dynamic_cast<B*>(aPtr);

чтобы получить указатель на базовый объект B из C , на который я указываю.

Я упоминаю об этом потому, что в то время, когда я пишу приведенный выше код, возможно, что компилятор еще не видел определение C , хотя он видел A и B . Это означает, что возможно компилятор не обнаружит какой-либо связи между A и B , но ему все равно придется скомпилировать код, потому что он ' Возможно, существует такой класс, как C , и dynamic_cast может быть успешным при некоторых обстоятельствах.

Проблема в том, что это означает, что я могу случайно выполнить перекрестное преобразование в объект неправильного типа. Предположим, у меня есть классы, которые выглядят следующим образом:

A   B    D
 \ /   
  C

Здесь D - некоторый случайный несвязанный класс. Если я попытаюсь написать что-то вроде этого:

A* aPtr = /* ... get a C* pointer ... */
D* dPtr = dynamic_cast<D*>(aPtr);

, то это dynamic_cast всегда будет терпеть неудачу во время выполнения, поскольку нет возможности соединить A и D . Если я использую D случайно, потому что я хотел использовать B , компилятор не даст мне никаких указаний на то, что у меня бессмысленное приведение.

Мой вопрос: Есть ли способ заставить компилятор предупреждать меня о том, что приведение всегда будет терпеть неудачу во время выполнения? Я был бы доволен решением на уровне языка или некоторыми настройками компилятора для любого основного компилятора, который мог бы обнаружить этот. Если есть внешний инструмент, это тоже хорошо; Я просто хочу знать, можно ли отловить этот класс ошибок.

8
задан GEOCHET 7 August 2015 в 14:44
поделиться