ProgrammazioneSviluppatore C++

Che cos'è 'friend' in C++? In quali casi è consigliato usare funzioni o classi friend, e quali sottigliezze di sicurezza e progettazione sorgono?

Supera i colloqui con l'assistente IA Hintsage

Risposta

La parola chiave friend consente a una certa funzione o a un'altra classe di avere accesso ai membri privati e protetti della classe in cui è dichiarato friend. Le funzioni friend possono essere sia globali che metodi di altre classi. Questa costruzione consente di implementare funzioni che richiedono accesso allo stato interno della classe, ma che non sono logicamente correlate all'interfaccia di quella classe.

È consigliato utilizzare friend:

  • Per implementare operatori di confronto, operatori matematici (operator<<, operator==, ecc.), quando le funzioni devono avere accesso ai membri privati di due oggetti contemporaneamente.
  • Quando una funzione esterna non è logicamente un metodo della classe, ma deve implementare parte del suo comportamento.
  • Per una stretta connessione tra classi che lavorano insieme (ad esempio, accesso ai dati privati di oggetti interni adiacenti).

Attenzione:

  • L'assegnazione di funzioni friend apre l'accesso ai dati privati e infrange l'incapsulamento.
  • L'abuso di friend può portare a un aumento della dipendenza nel codice e a un indebolimento della sicurezza.

Esempio:

class Box { int width; public: Box(int w): width(w) {} friend void printWidth(const Box &b); }; void printWidth(const Box &b) { std::cout << b.width << std::endl; }

Domanda insidiosa

Domanda: Può una funzione friend essere virtuale?
Risposta comune: Sì, poiché friend è un modificatore di funzione.
Risposta corretta: No, le funzioni friend non possono essere virtuali perché non sono membri della classe!

Esempio:

class Example { friend virtual void foo(); // Errore di compilazione: virtual non si applica a friend };

Esempi di errori reali dovuti alla mancanza di conoscenza delle sottigliezze del tema


Storia: Quando si progettava una libreria per matrici, tutti gli operatori aritmetici sono stati resi funzioni friend per velocizzare, ma si è dimenticata la compatibilità con la costanza e si è eccessivamente aperto l'accesso ai membri privati. Successivamente, nel progetto, altre funzioni alteravano accidentalmente lo stato interno della Matrix.



Storia: Nella sistema aziendale, le classi helper sono state rese friend tra loro per condividere l'accesso ai membri privati. Questo ha portato a dipendenze cicliche: aggiungere una nuova funzionalità richiedeva di modificare tutte le classi correlate. La successiva refattorizzazione ha richiesto settimane.



Storia: Per i test chiusi, si è deciso di rendere la classe di test friend alla classe di produzione. Quando sono apparsi vari set di unit test, è diventato impossibile tracciare quali metodi privati venivano effettivamente utilizzati; i test hanno iniziato a dipendere dall'implementazione interna, portando a una difficile manutenzione del codice.