Вопрос

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

class A
{
    ...
}

class B
{
    ...
}

class C : public A, public B
{
    ...
}

и где-то я обнаруживаю, что указатель класса B что у меня на самом деле указывает на класс C, но функция требует указателя на класс A, Что я могу сделать, чтобы получить этот указатель на класс A?

Это было полезно?

Решение

Если вы точно знаете, что у вас есть B* это указывает на C объект, вы можете использовать пару static_castS:

B* bp = new C();
C* cp = static_cast<C*>(bp);
A* ap = static_cast<A*>(cp);

Единственный способ отказаться от иерархии наследования - использовать dynamic_cast, который требует, чтобы тип полиморфной (то есть ваш класс должен иметь по меньшей мере одну функцию виртуального элемента; Поскольку ваши деструкторы базового класса должны быть virtual, Это обычно не проблема):

B* bp = new C();
A* ap = dynamic_cast<A*>(bp);

dynamic_cast Дополнительное преимущество в том, что если он не удается (то есть, если bp на самом деле не указывает на C), он возвращает NULL. Он имеет недостаток небольшой стоимости производительности (static_cast эффективно свободен во время выполнения).

Другие советы

Код

class A
{
};
class B
{
};
class C : public A, public B
{
};
int main() {
  C c;
  A *a = &c;
}

Действительно, так как C уже A, поэтому назначение действитеется.

Если C наследует от A, как вы показали, то указатель C * должен быть неявно конвертирован в указатель A *. Возможно ли, что вы не включали декларацию класса C, чтобы компилятор не знал об этом наследственным отношениям? Или что на самом деле есть разные отношения наследства, чем данные в вашем вопросе? Какой-то код будет полезен для диагностики этой проблемы.

Редактировать
На основании обновленной версии вашего вопроса:

// Converts b to type A*, but only if it is actually
// of type C; otherwise, returns NULL
A* convertBtoAviaC(B* b) {
   C* c = dynamic_cast<C*>(b);
   return c; // note may be NULL, if b is not a C
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top