Переключение между определяемыми пользователем классами во время выполнения в C ++
-
27-10-2019 - |
Вопрос
У меня есть два класса, один из которых расширяет другой.У них обоих есть метод, который называется doSomething()
которые выполняют что-то другое.Я хочу иметь один указатель, с которого я мог бы переключаться class A
Для class B
и пусть остальная часть кода выполняется одинаково, потому что у каждого из них одинаковое имя метода.Возможно ли это и правильный ли это способ сделать это?Кроме того, я довольно новичок в C ++, так что это может быть просто проблемой с этим.
class A {
void doSomething()
{
// does something
}
};
class B: public A {
void doSomething()
{
//does something else
}
};
main()
{
A *ptr = new A;
B *bptr = new B;
// a giant loop
ptr->doSomething();
if(condition)
{
ptr = bptr;
}
}
Решение
То, что вы пытаетесь достичь, называется полиморфизмом. В C ++ вам нужно будет определить общий (возможно, абстрактный) базовый класс C для A и B, сделайте что -то еще виртуальная функция, переопределите его как в A, так и B, и укажите указатели типа C*. Вот Хорошая вступительная статья по теме.
Другие советы
Я могу придумать два способа добиться этого.
Ваш способ хорош (с некоторыми небольшими изменениями), если у вас уже есть полиморфные типы).(Если B
является-an A
, логически)
class A
{
public:
virtual void f() { /* something */ };
};
class B : public A
{
public:
virtual void f() { /* something else */ };
};
int main()
{
A a;
B b;
A* c = 0;
// based on your condition
c = &a;
c->f();
c = &b;
c->f();
return 0;
}
Но что, если ваши типы на самом деле не так уж тесно связаны?Использование наследования подразумевает очень жесткую (в данном случае is-a) взаимосвязь между вашими классами.Является B
действительно A
?
Вот способ добиться этого для классов, которые имеют одну и ту же именованную функцию, но на самом деле не имеют похожих типов.
template <class T>
void do_f(T& obj)
{
obj.f();
}
class D
{
public:
void f() { /* something */ }
};
class E
{
public:
void f() { /* something else entirely */ }
};
int main()
{
// note, D and E have no relation
D d;
E e;
// based on your condition
do_f(d);
do_f(e);
}