- Articolo
C++ consente di specificare più di una funzione con lo stesso nome nello stesso ambito. Queste funzioni sono chiamatesovraccaricofunzioni, osovraccarichi. Le funzioni in overload consentono di fornire semantiche diverse per una funzione, a seconda dei tipi e del numero dei suoi argomenti.
Si consideri ad esempio astampa
funzione che richiede astd::stringa
discussione. Questa funzione potrebbe eseguire attività molto diverse rispetto a una funzione che accetta un argomento di tipoDoppio
. Il sovraccarico ti impedisce di dover usare nomi comestampa_stringa
Ostampa_doppio
. In fase di compilazione, il compilatore sceglie l'overload da usare in base ai tipi e al numero di argomenti passati dal chiamante. Se chiamistampa(42.0)
, poi ilstampa vuota (doppia d)
funzione viene richiamata. Se chiamiprint("ciao mondo")
, poi ilvoid print(std::string)
viene richiamato il sovraccarico.
È possibile sovraccaricare sia le funzioni membro che le funzioni libere. La tabella seguente mostra quali parti di una dichiarazione di funzione C++ utilizza per distinguere tra gruppi di funzioni con lo stesso nome nello stesso ambito.
Considerazioni sul sovraccarico
Elemento di dichiarazione di funzione | Usato per il sovraccarico? |
---|---|
Tipo di ritorno della funzione | NO |
Numero di argomenti | SÌ |
Tipo di argomenti | SÌ |
Presenza o assenza di puntini di sospensione | SÌ |
Uso ditypedef nomi | NO |
Limiti dell'array non specificati | NO |
cost Ovolatile | Sì, se applicato all'intera funzione |
Qualificatori di riferimento (& E&& ) | SÌ |
Esempio
L'esempio seguente illustra come utilizzare gli overload di funzioni:
// function_overloading.cpp// compila con: /EHsc#include #include #include // Prototipo di tre print functions.int print(std::string s); // Stampa una stringa.int print(double dvalue); // Stampa un double.int print(double dvalue, int prec); // Stampa un double con una // data precisione.using namespace std;int main(int argc, char *argv[]){ const double d = 893094.2987; if (argc < 2) { // Queste chiamate a print richiamano print( char *s ). print("Questo programma richiede un argomento."); print("L'argomento specifica il numero di"); print("precisione delle cifre del secondo numero"); print("stampato."); uscita(0); } // Richiama print( double dvalue ). stampa(d); // Richiama print( double dvalue, int prec ). print(d, atoi(argv[1]));}// Stampa una stringa.int print(stringa s){ cout << s << endl; return cout.good();}// Stampa un valore double in default precision.int print(double dvalue){ cout << dvalue << endl; return cout.good();}// Stampa un double con la precisione specificata.// I numeri positivi per precisione indicano quante cifre// precisione dopo la virgola decimale mostrare. I numeri negativi// per la precisione indicano dove arrotondare il numero// a sinistra della virgola decimale.int print(double dvalue, int prec){ // Usa la ricerca nella tabella per l'arrotondamento/troncamento. const statico double rgPow10[] = { 10E-7, 10E-6, 10E-5, 10E-4, 10E-3, 10E-2, 10E-1, 10E0, 10E1, 10E2, 10E3, 10E4, 10E5, 10E6 } ; const int iPowZero = 6; // Se la precisione non rientra nell'intervallo, stampa semplicemente il numero. if (prec < -6 || prec > 7) { return print(dvalue); } // Scala, tronca, quindi ridimensiona. dvalue = floor(dvalue / rgPow10[iPowZero - prec]) * rgPow10[iPowZero - prec]; cout << dvalue << endl; return cout.good();}
Il codice precedente mostra gli overload distampa
funzione nell'ambito del file.
L'argomento predefinito non è considerato parte del tipo di funzione. Pertanto, non viene utilizzato nella selezione delle funzioni in overload. Due funzioni che differiscono solo per gli argomenti predefiniti sono considerate definizioni multiple piuttosto che funzioni sovraccaricate.
Gli argomenti predefiniti non possono essere forniti per gli operatori in overload.
Corrispondenza degli argomenti
Il compilatore seleziona la funzione di overload da richiamare in base alla migliore corrispondenza tra le dichiarazioni di funzione nell'ambito corrente e gli argomenti forniti nella chiamata di funzione. Se viene trovata una funzione adatta, quella funzione viene chiamata. "Adatto" in questo contesto significa:
È stata trovata una corrispondenza esatta.
È stata eseguita una banale conversione.
È stata eseguita una promozione integrale.
Esiste una conversione standard nel tipo di argomento desiderato.
Esiste una conversione definita dall'utente (un operatore di conversione o un costruttore) nel tipo di argomento desiderato.
Sono stati trovati argomenti rappresentati da puntini di sospensione.
Il compilatore crea un insieme di funzioni candidate per ogni argomento. Le funzioni candidate sono funzioni in cui l'argomento effettivo in quella posizione può essere convertito nel tipo dell'argomento formale.
Per ogni argomento viene creato un insieme di "funzioni di migliore corrispondenza" e la funzione selezionata è l'intersezione di tutti gli insiemi. Se l'intersezione contiene più di una funzione, l'overload è ambiguo e genera un errore. La funzione che alla fine viene selezionata è sempre una corrispondenza migliore di ogni altra funzione nel gruppo per almeno un argomento. Se non c'è un chiaro vincitore, la chiamata alla funzione genera un errore del compilatore.
Si considerino le seguenti dichiarazioni (le funzioni sono contrassegnateVariante 1
,Variante 2
, EVariante 3
, per l'identificazione nella seguente discussione):
Frazione &Add( Frazione &f, long l ); // Variante 1Fraction &Add( long l, Fraction &f ); // Variante 2 Frazione &Aggiungi( Frazione &f, Frazione &f ); // Variante 3Frazione F1, F2;
Considera la seguente affermazione:
F1 = Aggiungi( F2, 23 );
L'istruzione precedente costruisce due insiemi:
Set 1: funzioni candidate che hanno il primo argomento di tipoFrazione | Set 2: funzioni candidate il cui secondo argomento può essere convertito in tipoint |
---|---|
Variante 1 | Variante 1 (int può essere convertito inlungo utilizzando una conversione standard) |
Variante 3 |
Le funzioni nel set 2 sono funzioni che hanno conversioni implicite dal tipo di parametro effettivo al tipo di parametro formale. Una di queste funzioni ha il "costo" minimo per convertire il tipo di parametro effettivo nel tipo di parametro formale corrispondente.
L'intersezione di questi due insiemi è la variante 1. Un esempio di chiamata di funzione ambigua è:
F1 = Aggiungi( 3, 6 );
La chiamata di funzione precedente crea i seguenti insiemi:
Set 1: funzioni candidate che hanno il primo argomento di tipoint | Set 2: funzioni candidate che hanno un secondo argomento di tipoint |
---|---|
Variante 2 (int può essere convertito inlungo utilizzando una conversione standard) | Variante 1 (int può essere convertito inlungo utilizzando una conversione standard) |
Poiché l'intersezione di questi due insiemi è vuota, il compilatore genera un messaggio di errore.
Per la corrispondenza degli argomenti, una funzione conNgli argomenti predefiniti vengono trattati comeN+1 funzioni separate, ciascuna con un diverso numero di argomenti.
I puntini di sospensione (...
) funge da carattere jolly; corrisponde a qualsiasi argomento effettivo. Può portare a molti set ambigui, se non si progettano i set di funzioni sovraccarichi con estrema cura.
Nota
L'ambiguità delle funzioni in overload non può essere determinata fino a quando non viene rilevata una chiamata di funzione. A quel punto, i set vengono creati per ogni argomento nella chiamata di funzione ed è possibile determinare se esiste un overload non ambiguo. Ciò significa che le ambiguità possono rimanere nel codice fino a quando non vengono evocate da una particolare chiamata di funzione.
Differenze di tipo di argomento
Le funzioni sovraccaricate distinguono tra tipi di argomenti che accettano inizializzatori diversi. Pertanto, un argomento di un determinato tipo e un riferimento a tale tipo sono considerati uguali ai fini dell'overload. Sono considerati uguali perché accettano gli stessi inizializzatori. Per esempio,massimo( doppio, doppio )
è considerato uguale amax( doppio &, doppio & )
. La dichiarazione di due di queste funzioni causa un errore.
Per lo stesso motivo, gli argomenti di funzione di un tipo modificato dacost
Ovolatile
non vengono trattati in modo diverso rispetto al tipo di base ai fini dell'overload.
Tuttavia, il meccanismo di sovraccarico della funzione può distinguere tra riferimenti qualificati dacost
Evolatile
e riferimenti al tipo di base. Rende possibile un codice come il seguente:
// argument_type_differences.cpp// compilare con: /EHsc /W3// C4521 atteso#include using namespace std;class Over {public: Over() { cout << "Over default constructor\n"; } Over( Over &o ) { cout << "Over&\n"; } Over( const Over &co ) { cout << "const Over&\n"; } Over( volatile Over &vo ) { cout << "volatile Over&\n"; }};int main() { Su o1; // Chiama il costruttore predefinito. Oltre o2( o1 ); // Richiama( Over& ). cost Oltre o3; // Chiama il costruttore predefinito. Sopra o4( o3 ); // Richiama( const Over& ). volatile Oltre o5; // Chiama il costruttore predefinito. Sopra o6( o5 ); // Richiama( volatile Over& ).}
Produzione
Over default costruttoreOver&Over default constructorconst Over&Over default constructorvolatile Over&
Puntatori acost
Evolatile
gli oggetti sono anche considerati diversi dai puntatori al tipo di base ai fini dell'overload.
Corrispondenza degli argomenti e conversioni
Quando il compilatore tenta di confrontare gli argomenti effettivi con gli argomenti nelle dichiarazioni di funzione, può fornire conversioni standard o definite dall'utente per ottenere il tipo corretto se non è possibile trovare una corrispondenza esatta. L'applicazione delle conversioni è soggetta alle seguenti regole:
Le sequenze di conversioni che contengono più di una conversione definita dall'utente non vengono prese in considerazione.
Le sequenze di conversioni che possono essere abbreviate rimuovendo le conversioni intermedie non vengono prese in considerazione.
La sequenza di conversioni risultante, se presente, è chiamata themigliore sequenza di corrispondenza. Esistono diversi modi per convertire un oggetto di tipoint
digitarelungo senza segno
utilizzando conversioni standard (descritte inConversioni standard):
Converti da
int
Alungo
e poi dalungo
Alungo senza segno
.Converti da
int
Alungo senza segno
.(Video) Meditazione per processare il sovraccarico di informazioni
Sebbene la prima sequenza raggiunga l'obiettivo desiderato, non è la migliore sequenza di corrispondenza, poiché esiste una sequenza più breve.
La tabella seguente mostra un gruppo di conversioni denominatebanali conversioni. Le conversioni banali hanno un effetto limitato sulla sequenza scelta dal compilatore come corrispondenza migliore. L'effetto delle conversioni banali è descritto dopo la tabella.
Conversioni banali
Tipo di argomento | Tipo convertito |
---|---|
nome-tipo | tipo-nome& |
tipo-nome& | nome-tipo |
nome-tipo[] | nome-tipo* |
nome-tipo(lista-argomento) | (*nome-tipo)(elenco-argomenti) |
nome-tipo | const nome-tipo |
nome-tipo | nome-tipo volatile |
nome-tipo* | const nome-tipo* |
nome-tipo* | nome-tipo volatile* |
La sequenza in cui vengono tentate le conversioni è la seguente:
Corrispondenza esatta. Una corrispondenza esatta tra i tipi con cui viene chiamata la funzione ei tipi dichiarati nel prototipo della funzione è sempre la corrispondenza migliore. Le sequenze di conversioni banali sono classificate come corrispondenze esatte. Tuttavia, le sequenze che non effettuano nessuna di queste conversioni sono considerate migliori delle sequenze che convertono:
Dal puntatore, al puntatore a
cost
(nome-tipo*
Aconst nome-tipo*
).Dal puntatore, al puntatore a
volatile
(nome-tipo*
Anome-tipo volatile*
).Dal riferimento, al riferimento a
cost
(tipo-nome&
Aconst nome-tipo&
).Dal riferimento, al riferimento a
volatile
(tipo-nome&
Atipo volatile&
).
Abbina usando le promozioni. Qualsiasi sequenza non classificata come corrispondenza esatta che contiene solo promozioni integrali, conversioni da
galleggiante
ADoppio
e le conversioni banali vengono classificate come corrispondenze utilizzando le promozioni. Sebbene non sia una corrispondenza valida come qualsiasi corrispondenza esatta, una corrispondenza che utilizza le promozioni è migliore di una corrispondenza che utilizza le conversioni standard.Corrispondenza utilizzando conversioni standard. Qualsiasi sequenza non classificata come corrispondenza esatta o una corrispondenza che utilizza promozioni che contiene solo conversioni standard e conversioni banali viene classificata come corrispondenza che utilizza conversioni standard. All'interno di questa categoria si applicano le seguenti regole:
La conversione da un puntatore a una classe derivata, a un puntatore a una classe base diretta o indiretta è preferibile alla conversione in
vuoto *
Ocost vuoto *
.La conversione da un puntatore a una classe derivata a un puntatore a una classe base produce una corrispondenza migliore quanto più la classe base è vicina a una classe base diretta. Supponiamo che la gerarchia delle classi sia come mostrato nella figura seguente:
Grafico che mostra le conversioni preferite.
Conversione da tipoD*
digitareC*
è preferibile alla conversione dal tipoD*
digitareB*
. Allo stesso modo, la conversione da typeD*
digitareB*
è preferibile alla conversione dal tipoD*
digitareUN*
.
Questa stessa regola si applica alle conversioni di riferimento. Conversione da tipoD&
digitareC&
è preferibile alla conversione dal tipoD&
digitareB&
, e così via.
Questa stessa regola si applica alle conversioni da puntatore a membro. Conversione da tipoTD::*
digitareTC::*
è preferibile alla conversione dal tipoTD::*
digitareT B::*
, e così via (doveT
è il tipo di membro).
La regola precedente si applica solo lungo un dato percorso di derivazione. Si consideri il grafico mostrato nella figura seguente.
Grafico dell'ereditarietà multipla che mostra le conversioni preferite.
Conversione da tipoC*
digitareB*
è preferibile alla conversione dal tipoC*
digitareUN*
. Il motivo è che sono sulla stessa strada eB*
è più vicino. Tuttavia, la conversione da typeC*
digitareD*
non è preferibile alla conversione in tipoUN*
; non c'è preferenza perché le conversioni seguono percorsi diversi.
Corrispondenza con conversioni definite dall'utente. Questa sequenza non può essere classificata come corrispondenza esatta, corrispondenza che utilizza promozioni o corrispondenza che utilizza conversioni standard. Per essere classificata come corrispondenza con conversioni definite dall'utente, la sequenza deve contenere solo conversioni definite dall'utente, conversioni standard o conversioni banali. Una corrispondenza con conversioni definite dall'utente è considerata migliore di una corrispondenza con i puntini di sospensione (
...
) ma non è una corrispondenza buona come una corrispondenza con le conversioni standard.(Video) Cosa sono e come si montano gli scaricatori di sovratensione di tipo 2? Pillola N.68Abbina con i puntini di sospensione. Qualsiasi sequenza che corrisponde a un'ellissi nella dichiarazione viene classificata come corrispondenza con un'ellissi. È considerata la partita più debole.
Le conversioni definite dall'utente vengono applicate se non esiste alcuna promozione o conversione incorporata. Queste conversioni vengono selezionate in base al tipo di argomento corrispondente. Considera il seguente codice:
// argument_matching1.cppclass UDC{public: operator int() { return 0; } operatore long();};void Print( int i ){};UDC udc;int main(){ Print( udc );}
Le conversioni definite dall'utente disponibili per la classeUDC
sono di tipoint
e tipolungo
. Pertanto, il compilatore considera le conversioni per il tipo di oggetto corrispondente:UDC
. Una conversione aint
esiste ed è selezionato.
Durante il processo di corrispondenza degli argomenti, le conversioni standard possono essere applicate sia all'argomento che al risultato di una conversione definita dall'utente. Pertanto, il seguente codice funziona:
void LogToFile( long l );...UDC udc;LogToFile( udc );
In questo esempio, il compilatore richiama una conversione definita dall'utente,operatore lungo
, convertireudc
digitarelungo
. Se nessuna conversione definita dall'utente al tipolungo
è stato definito, il compilatore convertirà prima il tipoUDC
digitareint
utilizzando il file definito dall'utenteoperatore int
conversione. Quindi applicherebbe la conversione standard dal tipoint
digitarelungo
per abbinare l'argomento nella dichiarazione.
Se è necessario che le conversioni definite dall'utente corrispondano a un argomento, le conversioni standard non vengono utilizzate durante la valutazione della corrispondenza migliore. Anche se più di una funzione candidata richiede una conversione definita dall'utente, le funzioni sono considerate uguali. Per esempio:
// argument_matching2.cpp// C2668 expectedclass UDC1{public: UDC1( int ); // Conversione definita dall'utente da int.};class UDC2{public: UDC2( long ); // Conversione definita dall'utente da long.};void Func( UDC1 );void Func( UDC2 );int main(){ Func( 1 );}
Entrambe le versioni diFunz
richiedono una conversione definita dall'utente per convertire il tipoint
all'argomento del tipo di classe. Le possibili conversioni sono:
Converti da tipo
int
digitareUDC1
(una conversione definita dall'utente).Converti da tipo
int
digitarelungo
; quindi convertire in tipoUDC2
(una conversione in due passaggi).
Anche se la seconda richiede sia una conversione standard che una conversione definita dall'utente, le due conversioni sono comunque considerate uguali.
Nota
Le conversioni definite dall'utente sono considerate conversione per costruzione o conversione per inizializzazione. Il compilatore considera entrambi i metodi uguali quando determina la migliore corrispondenza.
La corrispondenza degli argomenti e ilQuesto
puntatore
Le funzioni membro della classe vengono trattate in modo diverso, a seconda che siano dichiarate comestatico
.statico
funzioni non hanno un argomento implicito che fornisce ilQuesto
puntatore, quindi si ritiene che abbiano un argomento in meno rispetto alle normali funzioni membro. In caso contrario, vengono dichiarati in modo identico.
Funzioni membro che non lo sonostatico
richiedono l'implicitoQuesto
puntatore in modo che corrisponda al tipo di oggetto attraverso il quale viene chiamata la funzione. Oppure, per gli operatori sovraccaricati, richiedono che il primo argomento corrisponda all'oggetto a cui è applicato l'operatore. Per ulteriori informazioni sugli operatori in overload, vedereOperatori sovraccarichi.
A differenza di altri argomenti nelle funzioni sovraccaricate, il compilatore non introduce oggetti temporanei e non tenta alcuna conversione quando cerca di far corrispondere il fileQuesto
argomento del puntatore.
Quando il->
L'operatore di selezione dei membri viene utilizzato per accedere a una funzione membro della classenome della classe
, ILQuesto
argomento puntatore ha un tipo dinome_classe * cost
. Se i membri sono dichiarati comecost
Ovolatile
, i tipi sonoconst nome_classe * const
Enome_classe volatile * const
, rispettivamente.
IL.
L'operatore di selezione dei membri funziona esattamente allo stesso modo, tranne che un implicito&
L'operatore (indirizzo di) è preceduto dal nome dell'oggetto. L'esempio seguente mostra come funziona:
// Espressione incontrata in codeobj.name// Come viene trattata dal compilatore(&obj)->name
L'operando sinistro di->*
E.*
(puntatore al membro) gli operatori sono trattati allo stesso modo del.
E->
(selezione dei membri) rispetto alla corrispondenza degli argomenti.
Qualificatori di riferimento sulle funzioni membro
I qualificatori di riferimento consentono di eseguire l'overload di una funzione membro in base al fatto che l'oggetto puntato daQuesto
è un rvalue o un lvalue. Utilizzare questa funzionalità per evitare operazioni di copia non necessarie in scenari in cui si sceglie di non fornire l'accesso del puntatore ai dati. Ad esempio, supponi la classeC
inizializza alcuni dati nel suo costruttore e restituisce una copia di quei dati nella funzione membroottieni_dati()
. Se un oggetto di tipoC
è un rvalue che sta per essere distrutto, quindi il compilatore sceglie ilget_data() &&
sovraccarico, che sposta invece di copiare i dati.
#include #include usando namespace std;class C{public: C() {/*inizializzazione costosa*/} vector get_data() & { cout << "lvalue\n"; restituire _dati; } vettore get_data() && { cout << "rvalue\n"; return std::move(_data); }private: vector _data;};int main(){ C c; auto v = c.get_data(); // ottieni una copia. stampa "lvalue". auto v2 = C().get_data(); // recupera l'originale. stampa "rvalue" return 0;}
Restrizioni al sovraccarico
Diverse restrizioni regolano un insieme accettabile di funzioni sovraccaricate:
Due funzioni qualsiasi in un set di funzioni in overload devono avere elenchi di argomenti diversi.
L'overload di funzioni che hanno elenchi di argomenti dello stesso tipo, basati solo sul tipo restituito, è un errore.
Specifico Microsoft
Puoi sovraccaricare
operatore nuovo
in base al tipo restituito, in particolare, in base al modificatore del modello di memoria specificato.END Specifico per Microsoft
Le funzioni membro non possono essere sovraccaricate solo perché una lo è
statico
e l'altro nostatico
.typedef
le dichiarazioni non definiscono nuovi tipi; introducono sinonimi per tipi esistenti. Non influenzano il meccanismo di sovraccarico. Considera il seguente codice:typedef char * PSTR;void Print( char *szToPrint );void Print( PSTR szToPrint );
Le due funzioni precedenti hanno elenchi di argomenti identici.
PSTR
è sinonimo di tipocarattere *
. Nell'ambito del membro, questo codice genera un errore.I tipi enumerati sono tipi distinti e possono essere usati per distinguere le funzioni in overload.
I tipi "array of" e "pointer to" sono considerati identici ai fini della distinzione tra funzioni in overload, ma solo per array unidimensionali. Queste funzioni sovraccaricate entrano in conflitto e generano un messaggio di errore:
void Print( char *szToPrint );void Print( char szToPrint[] );
Per le matrici di dimensioni superiori, la seconda e le dimensioni successive sono considerate parte del tipo. Sono usati per distinguere tra funzioni sovraccaricate:
void Print( char szToPrint[] );void Print( char szToPrint[][7] );void Print( char szToPrint[][9][42] );
Sovraccaricare, ignorare e nascondere
Qualsiasi dichiarazione di due funzioni con lo stesso nome nello stesso ambito può fare riferimento alla stessa funzione oa due funzioni di overload discrete. Se gli elenchi di argomenti delle dichiarazioni contengono argomenti di tipi equivalenti (come descritto nella sezione precedente), le dichiarazioni di funzione fanno riferimento alla stessa funzione. In caso contrario, si riferiscono a due diverse funzioni che vengono selezionate utilizzando l'overload.
L'ambito della classe è rigorosamente rispettato. Una funzione dichiarata in una classe base non è nello stesso ambito di una funzione dichiarata in una classe derivata. Se una funzione in una classe derivata viene dichiarata con lo stesso nome di avirtuale
funzione nella classe base, la funzione della classe derivatasovrascrivela funzione della classe base. Per ulteriori informazioni, vedereFunzioni virtuali.
Se la funzione della classe base non è dichiarata comevirtuale
, allora si dice che la funzione di classe derivatanascondereEsso. Sia l'override che l'occultamento sono distinti dall'overload.
L'ambito del blocco è rigorosamente rispettato. Una funzione dichiarata nell'ambito file non è nello stesso ambito di una funzione dichiarata localmente. Se una funzione dichiarata localmente ha lo stesso nome di una funzione dichiarata nell'ambito del file, la funzione dichiarata localmente nasconde la funzione nell'ambito del file invece di causare l'overload. Per esempio:
// Declaration_matching1.cpp// compila con: /EHsc#include using namespace std;void func( int i ){ cout << "Chiamata funzione con ambito file : " << i << endl;}void func( char *sz ){ cout << "Chiamata localmente dichiarata func : " << sz << endl;}int main(){ // Dichiara func local to main. extern void func( char *sz ); funzione( 3 ); // Errore C2664. func( int ) è nascosto. funzione( "s" );}
Il codice precedente mostra due definizioni della funzionefunz
. La definizione che accetta un argomento di tipocarattere *
è locale aprincipale
a causa delesterno
dichiarazione. Pertanto, la definizione che accetta un argomento di tipoint
è nascosto e la prima chiamata afunz
è in errore.
Per le funzioni membro in overload, a diverse versioni della funzione possono essere assegnati privilegi di accesso diversi. Sono ancora considerate nell'ambito della classe di inclusione e quindi sono funzioni sovraccaricate. Si consideri il codice seguente, in cui la funzione membroDepositare
è sovraccarico; una versione è pubblica, l'altra privata.
Lo scopo di questo esempio è fornire unAccount
classe in cui è richiesta una password corretta per eseguire depositi. È fatto usando il sovraccarico.
La chiamata aDepositare
InConto::Deposito
chiama la funzione membro privato. Questa chiamata è corretta perchéConto::Deposito
è una funzione membro e ha accesso ai membri privati della classe.
// Declaration_matching2.cppclass Account{public: Account() { } double Deposit( double dAmount, char *szPassword );private: double Deposit( double dAmount ) { return 0.0; } int Validate( char *szPassword ) { return 0; }};int main(){ // Alloca un nuovo oggetto di tipo Account. Conto *pAcct = nuovo Conto; // Deposita $ 57,22. Errore: chiama una funzione privata. // pAcct->Deposito( 57.22 ); // Deposita $ 57,22 e fornisci una password. OK: chiama una // funzione pubblica. pAcct->Deposit( 52.77, "pswd" );}double Account::Deposit( double dAmount, char *szPassword ){ if ( Validate( szPassword ) ) return Deposito( dAmount ); altrimenti restituisce 0.0;}
Guarda anche
Funzioni (C++)