Il sovraccarico delle funzioni (overloading) è un meccanismo per dichiarare più funzioni con lo stesso nome, ma con firme diverse (numero o tipo di parametri).
I valori predefiniti per i parametri possono essere specificati nella dichiarazione delle funzioni. Sottigliezza: i valori predefiniti vengono considerati solo durante la compilazione della chiamata e vengono inseriti dal compilatore in base alla firma visibile.
Nelle classi si incontra spesso la situazione:
class Printer { void print(int n, char c = '*') { /* ... */ } void print(const std::string& s) { /* ... */ } }; Printer p; p.print(5); // chiamerà print(int n, char c = '*'), c = '*' p.print("Hi"); // chiamerà print(const std::string&)
Sottigliezze:
void foo(int x, int y = 10); void foo(int x); foo(1); // Errore: non è chiaro quale funzione chiamare
Qual è l'unico posto in cui è consentito specificare un valore predefinito per una funzione membro della classe?
Risposta: Il valore predefinito per il metodo di una classe può essere specificato nella dichiarazione del metodo all'interno della classe (o nella prima dichiarazione al di fuori della classe), ma non è consentito specificarlo sia nella classe che nell'implementazione. Altrimenti si verificherà un errore di ridichiarazione.
class X { void func(int x = 5); // Qui è possibile }; void X::func(int x) { /* ... */ } // Ma non qui!
Storia 1
Nel software bancario si è verificato un errore durante la fase di compilazione: parte delle funzioni sovraccaricate con valori predefiniti diversi ostacolavano la scelta univoca di quella necessaria, le chiamate erano ambigue durante la compilazione — risultato, impossibilità di compilare il rilascio fino alla correzione delle modifiche manuali.
Storia 2
Nella squadra era diffuso uno stile in cui tutti i valori predefiniti venivano spostati nell'implementazione e non nell'intestazione della classe, tuttavia per alcuni metodi delle classi ciò causava disallineamenti tra interfaccia e implementazione — diverse TU vedevano diversi parametri della funzione, portando a strani bug di compilazione e run-time.
Storia 3
Nell'espansione di una libreria pubblica è stato erroneamente aggiunto un sovraccarico della funzione con gli stessi parametri, ma con valori predefiniti diversi. Il compilatore ha iniziato a restituire ambiguità durante le chiamate API, e gli utenti si sono trovati di fronte a chiamate obsolete e problemi di compatibilità binaria.