2013-09-27 8 views
13

Ecco il codice ...Sono in grado di chiamare un metodo senza passare gli argomenti richiesti in C++. Come mai?

#include "stdafx.h" 
#include<iostream> 
using namespace std; 

class Base 
{ 
public: 
    virtual void Display(bool b = false) 
    { 
     cout<<"Base"<<"\t"<<b<<endl; 
    } 
}; 

class Derived : public Base 
{ 
public: 
    virtual void Display(bool b) override 
    { 
     cout<<"Derived"<<"\t"<<b<<endl; 
    } 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    Base* bp = new Base(); 
    Derived* dp = new Derived(); 
    bp->Display(); 
    dp->Display(true); 
    bp = new Derived(); 
    bp->Display(); 
    cout<<"Done"<<endl; 
    return 0; 
} 

Quando il Display() metodo chiamato seconda volta usando bp, a sorpresa ha colpito il metodo nella classe di Derived. nella classe Derived Non ho specificato l'argomento predefinito. Ma ha preso l'argomento della classe base di default. Come?

+0

Immagino tu intenda la terza volta (l'ultima volta nel tuo codice). – john

+0

Sì. Aggiorna la domanda ora. Grazie. –

+0

Porta indietro i ricordi: http://www.gotw.ca/gotw/005.htm. –

risposta

21

Questo sorprende molte persone, ma l'argomento predefinito è (o gli argomenti sono, se ne hai specificato più di uno) in base al tipo statico (il tipo al quale il puntatore è dichiarato di puntare) e non al tipo dinamico (il tipo di oggetto a cui capita attualmente di puntare).

Come tale, dal momento che si sta utilizzando Base *bp, vengono utilizzati gli argomenti di default dichiarati nel Base, indipendentemente dal fatto che bp capita di essere indicando un Base o un Derived.

Nel caso in cui ci si preoccupi del perché questo è: almeno nella tipica implementazione gli argomenti predefiniti sono effettivamente gestiti interamente in fase di compilazione. Il compilatore vede che hai chiamato un Display senza fornire un argomento e che Display ha un argomento con un valore predefinito. Pertanto, quando genera il codice per quella chiamata, il codice viene generato per passare il valore predefinito specificato. A quel tempo, non ha modo di indovinare se il puntatore potrebbe puntare su un tipo derivato quando la chiamata ha luogo, quindi tutto ciò che può fare è generare codice basato sul tipo statico. Anche se non è questo il caso, quando genera il codice per effettuare la chiamata, è anche possibile che possa operare su una classe derivata che non è stata ancora progettata o scritta, quindi utilizzando un valore specificato in quella classe derivata non sarebbe possibile

+0

Una buona cosa da tenere a mente – Cramer

+0

Se ricordo il mio C++, se hai aggiunto la parola chiave 'virtuale', il programma eseguirà comunque la funzione dal tipo di oggetto corrente. destra? –

+0

@STTLCU: Lo fa già. –

Problemi correlati