Domanda

Nel mio programma C ++:

#include<iostream.h>

class A
{
    public:
    virtual void func()
    {
         cout<<"In A"<<endl;
    }
};

class B:public A
{
    public:
    void func()
    {
        cout<<"In B"<<endl;
    }
};

class C:public B
{
    public:
    void func()
    { 
        cout<<"In C"<<endl;
    }
};  

int main()
{
    B *ptr=new C;
    ptr->func();
}

la dichiarazione dovrebbe chiamare B::func(). Tuttavia, la funzione, C::func() si chiama. Si prega di gettare un po 'di luce su questo. Una volta che la parola chiave virtuale viene rimossa in 'Classe A', questo non accade più.

È stato utile?

Soluzione

Per le basi si dovrebbe leggere C ++ FAQ Lite sulle funzioni virtuali .

  

Una funzione virtuale consente alle classi derivate sostituire l'attuazione fornita dalla classe base. Il compilatore si assicura la sostituzione è sempre chiamata ogni volta che l'oggetto in questione è in realtà della classe derivata, anche se l'oggetto si accede da un puntatore base anziché un puntatore derivato. In questo modo gli algoritmi della classe base da sostituire nella classe derivata, anche se gli utenti non conoscono la classe derivata.

Altri suggerimenti

Una volta funzione virtuale dichiarata sarà virtuale in tutte le classi derivate (non importa se si specifica esplicitamente o no). Così func () è virtuale nelle classi A, B e C.

la dichiarazione deve chiamare B :: func ()

Poiché i punti di puntatore a un oggetto di classe C, si chiamerà la funzione nella classe C.

Le funzioni virtuali portano a eseguire vincolante, il che significa che la funzione deve essere chiamata sarà tempo deciso in base all'oggetto puntato dal puntatore, non il tipo di puntatore dichiarato al momento della compilazione.

Questa è l'essenza di polimorfismo. La funzione principale non ha bisogno di conoscere la ptr è in realtà puntando a un oggetto della classe C, ha solo bisogno di sapere che l'interfaccia disponibile è almeno quello che è definito nella classe B (che è il motivo per cui si dichiara come B *ptr, se avevi bisogno di funzioni specifiche per C, si dovrebbe fare C *ptr).

Quando si dice la funzione è virtuale in B, vuol dire che può essere sovraccaricato da una sottoclasse, e il compilatore genera il codice che appare per questa implementazione alternativo. In questo caso, si trova in C (i dati reali potrebbero differire da compilatore a compilatore, ma la maggior parte compilatori permettere all'oggetto portare una tabella con esso, la cosiddetta tabella virtuale, mappatura func() ad una specifica implementazione), e chiede che uno .

Se non c'è parola chiave virtuale, questo dice al compilatore che non ci può essere un'implementazione alternativa, e hard-collega alla B-implementazione direttamente.

Se avresti fatto:

B *obj = new B;

Poi avrebbe chiamato B :: func ().
Per atchive il functionallity vi aspettate è necessario rimuovere la nuova implementazione di func in C.
Se si utilizza una funzione virtuale in realtà dire che non so che tipo di oggetto che ho dentro finché è della stessa famiglia di oggetti (in questo A è il "padre" della "famiglia"). Tutto quello che sai è che ogni membro della "famiglia" ha a che fare un lavoro diverso per una parte specifica. Per esempio:

class Father
{
public:
  virtual void func() { cout << "I do stuff"; }
};
class Child : public Father
{
public:
  virtual void func() { cout << "I need to do something completely different"; }
};

int main()
{
  Father *f = new Father;
  f->func(); // output: I do stuff
  delete f;
  f = new Child;
  f->func(); // output: I need to do something completely different
  delete f;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top