c Множественное наследование и приведение

#c #multiple-inheritance

#c #множественное наследование

Вопрос:

У меня есть следующие классы :

 class A { };
class B { 
public:
B(){}
virtual ~B(){};
};
class B1 : public B{ 
public:
B1(){}
virtual ~B1(){};
};
class B2 : public B{ 
public:
B2(){}
virtual ~B2(){};
};
class C1 : public A, public B1{ 
public:
C1(){}
virtual ~C1(){};
};
class C2 : public A, public B2{ 
public:
C2(){}
virtual ~C2(){};
};
  

Я хочу знать, является ли объект типа B также типом A :

   B*b = new C1(); // or new B, or new C2 ...

  if(dynamic_cast<A*>(b))
  {
    ...
  

Правильно ли мой dynamic_cast делает это (он компилируется и запускается)?
Спасибо.

Комментарии:

1. Я думаю, что ваш гипс недействителен. То, что у A и B есть общие дети, не означает, что они могут быть привязаны друг к другу.

2. Ваш b , хотя вы объявили его как B* созданный с new C1() помощью, так что это законно A* , и ваш код будет работать. Если вы попытаетесь new B() , это не удастся. C1 наследует от A , но B не делает этого.

Ответ №1:

Чтобы иметь возможность использовать dynamic_cast всех родителей объекта, он должен быть полиморфным. Т.Е. вам нужно добавить в класс хотя бы одну виртуальную функцию A (например, деструктор).

Как только вы это исправите, все dynamic_cast будет в порядке.

Ответ №2:

Класс A отличается от класса B в системе типов C . Поскольку они оба пусты, они должны быть одинаковыми, как бы они ни были установлены в памяти. Даже пустые классы имеют свойство identity.

dynamic_cast<new_type> (expression) обычно используется как: dynamic_cast<derived_type> (myBase) . В этом случае «Если выражение является указателем или ссылкой на базовый полиморфный тип, а new_type является указателем или ссылкой на производный тип, выполняется проверка во время выполнения:» см cppreference.com найдите dynamic_cast. Это позволяет вам привести базовый класс обратно к производному классу. Программист должен знать, что производный класс существует.

Комментарии:

1. Вы говорите, что тело оператора if выполняется, поскольку все допустимые указатели не равны нулю, но если dynamic_cast<>() завершается с ошибкой, он возвращает 0, поэтому способ проверки результата является подходящим. «Если приведение выполнено успешно, dynamic_cast возвращает значение типа new_type. Если приведение завершается неудачно, а new_type является типом указателя, он возвращает нулевой указатель этого типа. Если приведение завершается с ошибкой, а new_type является ссылочным типом, оно генерирует исключение, соответствующее обработчику типа std::bad_cast.»

2. Спасибо, я исправлю свой ответ