Video: Programmazione in C++ • I File 2024
In C ++, solo perché si pensa che una particolare chiamata di funzione sia legata in ritardo non significa che lo sia. Se non dichiarato con gli stessi argomenti nelle sottoclassi, le funzioni membro non vengono sovrascritte in modo polimorfico, indipendentemente dal fatto che siano dichiarate virtuali.
Un'eccezione alla regola di dichiarazione identica è che se la funzione membro nella classe base restituisce un puntatore o un riferimento a un oggetto classe base, una funzione membro sottoposto a override in una sottoclasse può restituire un puntatore o un riferimento a un oggetto della sottoclasse. In altre parole, la funzione makeACopy () è polimorfica, anche se il tipo di ritorno delle due funzioni differisce:
class Base {public: // restituisce una copia dell'oggetto corrente Base * makeACopy ();}; class SubClass: public Base {public: // restituisce una copia dell'oggetto attuale SubClass * makeACopy ();}; void fn (Base & bc) {Base * pCopy = bc. fare una copia(); // continua su …}
In pratica, è abbastanza naturale. Una funzione makeACopy () dovrebbe restituire un oggetto di tipo Sottoclassella , anche se potrebbe sovrascrivere BaseClass:: makeACopy () .
Questo business di decidere in silenzio quando una funzione è sovrascritta e quando non è una fonte di errore in C ++; tanto che lo standard 2011 ha introdotto il descrittore override che il programmatore può utilizzare per indicare il suo intento di scavalcare una funzione di classe base.
C ++ genera un errore del compilatore se una funzione è dichiarata sovrascritta, ma, di fatto, non sovrascrive una funzione della classe base per qualche motivo (come un argomento non corrispondente) come nell'esempio seguente: >
Questo snippet genera un errore in fase di compilazione poiché il metodo GradStudent:: addCourseGrade (float) è stato dichiarato override, ma in realtà non sovrascrive la funzione della classe base Student:: addCourseGrade (double) perché il tipo di argomento non viene visualizzato t partita.
Il programmatore può anche dichiarare una funzione non sovrascrivibile usando la finale parola chiave, anche se quella funzione stessa sovrascrive alcune funzioni della classe base precedenti, come dimostrato nel seguente > PostDoc class: class GradStudent: public Student {public: virtual void addCourseGrade (double grade) final;}; classe PostDoc: public GradStudent {public: virtual void addCourseGrade (double grade);}; Poiché Studente:: addCourseGrade () è contrassegnato come finale
,
la dichiarazione di PostDoc:: addCourseGrade () genera un errore perché tenta di ignorare il metodo Studente .
class GradStudent final: public Student Ciò riguarda più dei semplici metodi virtuali della classe. Una classe
finale
non può essere ereditata affatto.