Переключение между пользовательскими классами во время выполнения в C ++ - PullRequest
1 голос
/ 01 декабря 2011

У меня есть два класса, один из которых расширяет другой.У них обоих есть метод с именем 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;
    }
}

Ответы [ 2 ]

5 голосов
/ 01 декабря 2011

Есть два способа сделать это.

Ваш путь в порядке (с небольшими изменениями), если у вас уже есть полиморфные типы).(Если B is-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;
}

Но что, если ваши типы на самом деле не так тесно связаны?Использование наследования подразумевает очень жесткие (в данном случае) отношения между вашими классами.Является ли 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);
}
2 голосов
/ 01 декабря 2011

То, что вы пытаетесь достичь, называется полиморфизмом.В C ++ вам нужно будет определить общий (возможно абстрактный) базовый класс C для A и B, сделать doSomething виртуальной функцией , переопределить его в A и B и создать указатели типа C *.Вот хорошая вводная статья на эту тему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...