2012-01-11 13 views
10

Sto testando solo con parole chiave virtuali e concetti di ereditarietà in C++. Ho scritto un piccolo programma:Sovraccarico di una funzione virtuale in una classe figlia

#include<stdio.h> 
#include<iostream> 

using namespace std; 

class cna_MO 
{ 
    public: 
    virtual void print() 
    { 
     cout << "cna_MO" << endl; 
    } 
}; 

class cna_bsc:public cna_MO 
{ 
    public: 
    void print() 
    { 
     cna_MO::print(); 
    } 

    void print(int a) 
    { 
     cout << "cna_BSC" << endl; 
    } 
}; 

class cna_Mo 
{ 
    cna_MO *_mo; 

    public: 
    cna_Mo() 
    { 
     _mo = new cna_bsc; 
    } 

    virtual void print(int a) 
    { 
     cout << "cna_Mo with arg" << endl; 
     _mo->print(5); 
    } 

    virtual void print() 
    { 
     cout << "cna_Mo" << endl; 
     _mo->print(); 
    } 
}; 

int main() 
{ 
    cna_Mo valid_mo; 
    cout << "old case is started" << endl; 
    valid_mo.print(); 
    cout << "new case is started" << endl; 
    valid_mo.print(5); 
    return 0; 
} 

Quello che ho fatto qui è che ho sovraccaricato una funzione virtuale nella classe genitore in classe bambino! Non è questa la cosa giusta da fare?

sto ottenendo gli errori di compilazione, come di seguito:

"temp10.cc", line 45: Error: Too many arguments in call to "cna_MO::print()".

+1

Se hai veramente bisogno di 'stdio' (non è necessario nel codice che hai fornito), [dovresti includere' cstdio' piuttosto che 'stdio.h'] (http://stackoverflow.com/domande/301.586/what-is-the-differenze-tra-con-includefilename-e-includefilename-h). –

+0

Inoltre, non si elimina mai il puntatore che si assegna nel costruttore cna_Mo. –

risposta

23

volta sovraccaricate una funzione dalla classe base nella classe derivata tutte le funzioni con lo stesso nome nella classe Base vengono nascosti in classe derivata.

Dopo aver aggiunto la funzione cna_bsc::print(int a) alla classe derivata, la funzione cna_MO::::print() non è più visibile agli utenti della classe Derivata. Questo è noto come nascondiglio della funzione.

Soluzione: Al fine di rendere la funzione nascosta visibile in classe derivata, è necessario aggiungere:

using cna_MO::print; 

nella sezione public della classe derivata cna_bsc.

Buona Lettura:

What's the meaning of, Warning: Derived::f(char) hides Base::f(double)?

+0

Ho capito il tuo punto di vista, ma ho ancora un altro problema ... ho modificato la domanda. Controlla la domanda adesso. Anche dopo aver apportato le modifiche, sto ottenendo troppi errori. – Vijay

+3

L'errore è in 'cna_MO :: print()' quando chiamate '_mo-> print (5);' notate che '_mo' è del tipo' cna_MO * 'e la classe' cna_MO' non ha 'print() 'funzione che accetta un singolo argomento e quindi l'errore. Il motivo della tua confusione è usnig che confonde nomi di classi non distinti, ** NON UTILIZZARE MAI LA CONVENZIONE DI NOMI COME QUELLO ** –

0

È perché la funzione di stampa nella classe bambino prende un parametro e l'originale non lo fa.

a cna_MO (classe genitore):

virtual void print() 

a cna_bsc (classe figlia):

void print(int a) 

Fondamentalmente stampa del bambino non dovrebbe prendere un argomento int:

void print() 

MODIFICA:

Forse la cosa migliore sarebbe fare passare l'int opzionale?

esempio:

a cna_MO (classe genitore):

virtual void print(int a=-1) { 
    if (a == -1) { 
     // Do something for default param 
    } else { 
     cout << a; 
    } 
} 

a cna_bsc (classe figlia):

void print(int a=-1) 

quindi se a == -1 probabilmente si può supporre, non hanno passato nulla.

Il trucco è che sia il genitore che il bambino hanno bisogno dello stesso metodo siganture, che significa lo stesso tipo di ritorno e gli stessi tipi di argomento.

+0

Vedi la domanda modificata – Vijay

+0

Ora è perché stai provando a chiamarlo passando un int su quella linea: ' valid_mo.print (5); ' – matiu

0

Quando si ha una funzione con lo stesso nome e diversi parametri nella classe derivata come quella della classe base, tale funzione sarà nascosta. È possibile trovare maggiori informazioni here ..

È possibile richiamare la funzione specifica nascosto chiamando come Base::hiddenFun();

+0

vedere la domanda modificata – Vijay

0

che non possono lavorare a causa dato un cna_MO *, si può vedere a tempo di compilazione che l'oggetto appuntito non lo fa (necessariamente) hanno il sovraccarico int. Se in realtà puntava a un oggetto di classe base, _mo->print(5); non avrebbe davvero nulla da chiamare. Inoltre, può esistere un numero infinito di classi derivate (non ancora implementate) che non devono supportare questa chiamata.

  1. Ogni classe derivata deve avere print(int) - dichiararlo nella classe base.

  2. Ogni classe derivata non deve avere print(int)-cna_Mo funziona solo con cna_bsc, in modo che il membro dovrebbe essere cna_bsc* _mo.

0

Idealmente la vostra stampa che prende un int dovrebbe avere un nome diverso, ma dato che si desidera entrambe le funzioni per essere chiamato di stampa, si dovrebbe fare tutti e due non virtuale e fare li chiamano funzioni virtuali protette.

class cna_MO 
{ 
    public:  
    void print() { doPrint(); } 

    protected: 
    virtual void doPrint() 
     {   cout << "cna_MO" << endl;  
     } 
}; 


class cna_bsc:public cna_MO 
{ 
    protected:  
     virtual void doPrint() 
        // although with implementation no need to override it 
     {   
      cna_MO::print();  
     } 

    public: 
    void print(int a)  
     { 
      doPrintInt(a); 
     } 

    protected: 
     virtual void doPrintInt(int) 
     { 
     cout << "cna_BSC" << endl;  
     } 
}; 
0

se proprio deve fare in questo modo, vale a dire hanno un puntatore a una classe e inizializzare come una classe derivata, non c'è altra scelta che lanciare sempre il puntatore al tipo corretto quando lo si utilizza. In questo caso, ((cna_bsc*)_mo)->print(5);

Problemi correlati