Почему этот перекрестный бросок не разрешен? - PullRequest
0 голосов
/ 06 января 2020

Рассмотрим этот простой пример:

struct Base1 {};

struct Base2 {};

struct Derived : public Base1, public Base2 {};

int main()
{
   Derived foo;
   Base1* foo1 = &foo;
   Base2* foo2 =  static_cast<Base2*>(foo1); 
}

Я получаю:

Error: static_cast from 'Base1 *' to 'Base2 *', which are not related by inheritance, is not allowed

Компилятор должен иметь достаточно информации, чтобы выяснить, что Base2 может быть достигнуто с Derived без RTTI (dynamic_cast) и заставляет меня делать:

Derived* foo3 = static_cast<Derived*>(foo1);
Base2* foo2 = foo3;

Почему это не разрешено? (Можно утверждать, что компилятор не знает, имеет ли foo1 тип Derived, но static_cast не проверяет тип в любом случае, даже при преобразовании, например, из Base1 в Derived)

Примечание: этот вопрос похож на мой, но не совсем так, потому что здесь мы кросс-кастинг базовых классов, а не производных

1 Ответ

3 голосов
/ 06 января 2020

A static_cast потерпит неудачу, поскольку, неофициально говоря, Base1 и Base2 не связаны между собой.

Однако dynamic_cast будет работать, если ваши классы polymorphi c: чего вы можете достичь, добавив виртуальные деструкторы:

struct Base1 {virtual ~Base1() = default;};

struct Base2 {virtual ~Base2() = default;};

struct Derived : Base1, Base2 {};

int main()
{
   Derived foo;
   Base1* foo1 = &foo;
   Base2* foo2 =  dynamic_cast<Base2*>(foo1); 
}

Это приведение от Base1 к Base2 идиоматично c при работе с композиция (то есть интерфейсы) .

...