Domanda

Ho due classi con uno che si estende l'altro. Entrambi hanno un metodo chiamato doSomething() che eseguono qualcosa di diverso. Voglio essere in grado di avere un puntatore che posso passare da class A a class B e avere il resto del codice eseguire lo stesso, perché ognuno ha lo stesso nome del metodo. Questo è possibile, ed è questo il modo corretto per farlo? Inoltre, sono abbastanza nuovo per C ++ in modo che possa essere solo un problema con questo.

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;
    }
}
È stato utile?

Soluzione

Che cosa si sta cercando di ottenere è chiamato polimorfismo. In C ++, è necessario definire un comune (possibilmente abstract) classe di base C per A e B, fare doSomething un funzione virtuale , sostituirla in entrambi a e B, e fare puntatori di tipo C *. Ecco una buon articolo introduttivo sul tema.

Altri suggerimenti

Due modi mi viene in mente per raggiungere questo obiettivo.

Il tuo modo va bene (con alcune piccole modifiche) se si dispone già di tipi polimorfi). (Se B è-un A, logicamente)

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;
}

Ma cosa succede se i vostri tipi non sono poi così strettamente correlati? Utilizzando l'ereditarietà implica una (is-a, in questo caso) rapporto molto rigido tra le classi. È un B davvero un A?

Ecco un modo per raggiungere questo obiettivo per le classi che hanno la stessa funzione denominata, ma in realtà non sono dei tipi simili.

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);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top