2014-11-04 17 views
9

Sono confuso riguardo le differenze tra ridefinire e sovrascrivere le funzioni nelle classi derivate.Redefinire e sovrascrivere in C++

So che - In C++, le funzioni ridefinite sono collegate staticamente e le funzioni sottoposte a override sono vincolate dinamicamente e che una funzione virtuale viene sovrascritta e una funzione non virtuale viene ridefinita.

Quando una classe derivata "ridefinisce" un metodo in una classe base, la sua viene considerata ridefinita. Ma quando una classe derivata è virtuale, non ridefinisce più, ma piuttosto sovrascrive. Quindi capisco la logistica delle regole ma non capisco la linea di fondo.

Nell'esempio seguente la funzione SetScore viene ridefinita. Comunque se faccio la funzione setScore nella classe base virtuale (aggiungendo la parola virtual ad esso) il setScore nella classe derivata verrà sovrascritto. Non capisco la linea di fondo - qual è la differenza. in setScore?

La classe di base:

class GradedActivity 
{ 
protected: 
    char letter;   // To hold the letter grade 
    double score;   // To hold the numeric score 
    void determineGrade(); // Determines the letter grade 
public: 
    // Default constructor 
    GradedActivity() 
    { letter = ' '; score = 0.0; } 

// Mutator function 
    void setScore(double s) 
     { score = s; 
     determineGrade();} 

    // Accessor functions 
    double getScore() const 
     { return score; } 

     char getLetterGrade() const 
     { return letter; } 
}; 

La classe derivata:

class CurvedActivity : public GradedActivity 
{ 
protected: 
    double rawScore;  // Unadjusted score 
    double percentage; // Curve percentage 
public: 
    // Default constructor 
    CurvedActivity() : GradedActivity() 
     { rawScore = 0.0; percentage = 0.0; } 

    // Mutator functions 
    void setScore(double s) 
     { rawScore = s; 
     GradedActivity::setScore(rawScore * percentage); } 

    void setPercentage(double c) 
     { percentage = c; } 

    // Accessor funtions 
    double getPercentage() const 
     { return percentage; } 

    double getRawScore() const 
     { return rawScore; } 
}; 

Questo è il principale:

// Define a CurvedActivity object. 
    CurvedActivity exam; 

    ... 

    // Send the values to the exam object. 
    exam.setPercentage(percentage); 
    exam.setScore(numericScore); 
+0

Overriding facilita il polimorfismo di classe. Il sovraccarico facilita il polimorfismo funzionale. La ridefinizione non fa né ed è un errore. – orfdorf

risposta

14

Qui sono alcune differenze fondamentali:

Un overloaded function è una funzione che condivide il suo nome con una o più altre funzioni, ma che ha un diverso elenco di parametri. Il compilatore sceglie quale funzione è desiderata in base agli argomenti utilizzati.

Un sostituito funzione è un metodo in una classe discendente che ha una definizione diversa rispetto a una funzione virtuale in una classe di antenato. Il compilatore sceglie quale funzione è desiderata in base al tipo di oggetto utilizzato per chiamare la funzione.

A ridefinito la funzione è un metodo in una classe discendente che ha una definizione diversa rispetto a una funzione non virtuale in una classe di antenato. Non farlo. Poiché il metodo non è virtuale, il compilatore sceglie quale funzione chiamare in base al tipo statico del riferimento all'oggetto anziché al tipo effettivo dell'oggetto.

  • tipo statico controllando significa che la verifica del tipo si verifica al momento della compilazione. In questo caso non vengono utilizzate informazioni di tipo in fase di esecuzione.

  • Il controllo dinamico del tipo si verifica quando le informazioni sul tipo vengono utilizzate in fase di esecuzione. C++ utilizza un meccanismo chiamato RTTI (informazioni sul tipo di runtime) per implementarlo. L'esempio più comune in cui RTTI viene utilizzato è l'operatore dynamic_cast che consente il downcasting di tipi polimorfi:

+0

Grazie, questo può essere stupido ma cosa vuol dire: tipo statico del riferimento all'oggetto. – YelizavetaYR

+0

Sovraccarico di funzioni solo se nello stesso ambito. Potrebbe voler aggiungere questo. – Deduplicator

+3

* "Il compilatore sceglie quale funzione è desiderata in base al tipo di oggetto utilizzato per chiamare la funzione." * Non è corretto, il compilatore non decide nulla. La decisione viene eseguita in fase di esecuzione tramite la ricerca vtable. – Manu343726