LittleFatNinja
@LittleFatNinja
горе девелопер, любитель лютой садомии

C++ как вызвать метод потомка, не определоного в предке?

я понимаю что в А нет метода getSome(), но он есть в классе В, а в foo() я как раз и передаю экземпляр класса В
class A {

}

class B : A {
  int getSome();
}

void foo(A& a) {
  a.getSome(); //error: class 'A' has no member 'getSome()'
}

int main() {
   B b();
   foo(b);
}
  • Вопрос задан
  • 1961 просмотр
Решения вопроса 2
В класс А добавить виртуальный деструктор:

class A
{
public:
virtual ~A(){}
};

после этого:

void foo(A& a)
{
   if (B* b = dynamic_cast<B*>(&a))
      b->getSome();
}
Ответ написан
@monah_tuk
Для начала: не пишите так.

А так, если классы именно такие, то memory layout у них просто и, грубо, они указывают а одну область памяти. Поэтому поможет простое приведение:
void foo(A& a) {
  //a.getSome(); //error: class 'A' has no member 'getSome()'
  static_cast<B&>(a).getSome(); // All ok.
}


Более того, у вас ещё косяк, такой код:
B b();
это не то, что вы подумали, это объявление функции. Всё что выглядит как функция, крякает как функция - функция. Правильно так:
B b; // дефолтный конструктор не для POD типов вызовется и так

или так:
B b = B(); // Накладных расходов не будет. Будет вызван ТОЛЬКО один консутрутор. Компиляторы не совсем дураки.


Кроме того, надеюсь, класс B описан, на самом деле, как-то так:
class B : <b>public</b> A {
<b>public:</b>
  int getSome();
};

а не так как у вас.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
PavelK
@PavelK
Через приведение типов?
Пардон, не получится - словите эксепшн, т.к. в классе A нет реализации функции.

По-моему никак. Нужно перепродумывать архитектуру.

Либо перенести этот метод в другой класс, от него наследовать A и B а потом уже и можно приведение типов.
Ответ написан
Комментировать
RiseOfDeath
@RiseOfDeath
Диванный эксперт.
Вообще, если ваша функция foo принимает объекты типа A, то она не должна вызывать функции, которых у этого объекта нет. Т.е. грубо говоря класс A задает "интерфейс" для всех потомков, который должны дергать всякие функции foo.

Т.е. в ваш пример должен выглядеть как-то так:

class A {
virtual int getSome()=0;
}

class B : A {
int getSome();
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы