Call by value per le classi c ++ decisione progettuale [closed]

2

Mi chiedo perché C ++ usi 'call by value' per le classi come predefinite? Immagino che questo potrebbe avere vantaggi nel senso della performance (velocità). Intendo C # e le classi di passaggio Java come riferimenti predefiniti.

Quali sono i motivi per cui C ++ passa le classi come copie di default?

    
posta GrayFox 09.10.2015 - 12:16
fonte

3 risposte

7

Stai lavorando su un equivoco:
Java e C sono sempre pass-by-value, C # e C ++ solo per impostazione predefinita.
(C # ha out e ref argomenti, C ++ ha riferimenti.)

La differenza tra C ++ e Java / C # è che negli ultimi due puoi sempre ottenere un puntatore (chiamato riferimento) a un class -type (o qualsiasi altro cosiddetto tipo di riferimento, e solo a quelli ).

E perché è l'unico modo predefinito di default per valore ?
Coerenza, sicurezza e semplicità. È il modo più semplice e riduce la modifica non intenzionale degli argomenti.
Ad ogni modo, è facile emulare pass-by-reference (o aggiungere la sintassi per farlo) a partire da quel punto, poiché emula pass-by-value in un altro modo.

    
risposta data 09.10.2015 - 14:19
fonte
4

Per C ++, la risposta è semplice: le classi sono struct s (o viceversa) e struct s vengono passati per valore perché vengono passati per valore in C. Ciò garantisce che un sottoinsieme utilizzabile di C può essere compilato come codice C ++.

Per C, non è così semplice. Ma C ha la caratteristica unica che non ha riferimenti impliciti. Qualsiasi cosa utilizzi un riferimento implicito in altri linguaggi utilizza un puntatore esplicito in C. (L'unica cosa implicita sui puntatori in C è il decadimento implicito di matrici e nomi di funzioni in puntatori).

Questa caratteristica del puntatore esplicito ha due effetti benefici:

  1. Aiuta a mantenere il linguaggio semplice.

    Se hai riferimenti impliciti, devi quantomeno distinguere tra la creazione di un riferimento e l'assegnazione dei dati dietro quel riferimento, come fa il C ++. O devi rendere gli oggetti non assegnabili come fa Java. O devi avere una sintassi speciale per assegnare il riferimento come fa Fortran.

    In entrambi i casi, la complessità del linguaggio e del compilatore viene sommata allo schema puntatore esplicito. Tuttavia, questi puntatori espliciti ti consentono di fare qualsiasi cosa che altri linguaggi fanno con riferimenti impliciti aggiungendo solo occasionalmente * o & , o scambiando un -> per un . .

  2. Facilita il ragionamento su quale memoria può essere toccata da una chiamata di funzione. Quando vedi una chiamata come foo(myStruct) , sai che foo() non può cambiare myStruct senza nemmeno guardare la dichiarazione di foo() . D'altra parte, foo(&myStruct) dà un strong segnale che myStruct non sarà lo stesso dopo la chiamata.

    Considero i riferimenti C ++ come un passo indietro in questo senso.

Sulla considerazione della prestazione: è impossibile dire che sia il valore per il pass-by che il riferimento per il pass-by sono più veloci in generale. La verità è che il pass-by-value è più veloce per i tipi semplici e il pass-by-reference è più veloce per i tipi complessi.

I progettisti di C devono aver saputo che la maggior parte di struct s sarebbe più veloce con il pass-by-reference. Credo che abbiano scelto un linguaggio "pass-by-value" in ogni caso perché sentivano che il passaggio di riferimenti impliciti è dannoso per la semplicità del linguaggio con effetti dubbi sulla sua fruibilità.

    
risposta data 09.10.2015 - 14:06
fonte
1

Di gran lunga il motivo più importante per cui è fatto in questo modo è la coerenza.

Ecco come viene passato tutto il resto, quindi perché non anche le strutture e le classi?

Una delle principali giustificazioni per attenersi a questa coerenza è che in C e C ++ devi essere sempre attento alle indirette, (e quante di esse rappresentano una determinata variabile), quindi l'approccio generale adottato dalla lingua è di evitare di nascondersi indirette dal programmatore. In questo modo, tutto ciò che non è adornato con un '&' viene passato per valore, a meno che la funzione stessa non dichiari che l'argomento è un riferimento, nel qual caso non è necessario fornire "&" quando chiami e invece devi ricordare che c'è un '&' nella parte ricevente. (Ma tu hai fatto questa scelta, quindi hai portato su di te questo ulteriore carico mentale.)

Un'altra giustificazione è che se le strutture e le classi dovessero essere un'eccezione alla regola di passare tutto per valore, allora il linguaggio dovrebbe comunque darti un modo per specificare che in effetti vuoi una struttura / classe occasionale per essere passati per valore, e quindi quali brutte modifiche subirebbe la sintassi della lingua per facilitare questo? Il linguaggio ha già la sintassi per prendere un riferimento a qualcosa, ma non per trasmettere il valore di qualcosa.

Nota: il mio C ++ potrebbe essere un po 'arrugginito, quindi potrei aver fatto qualche piccolo errore o usare una parola un po' sbagliata per qualcosa. Se lo sai meglio, è del tutto possibile, ma invece di downvoting, modifica la risposta per correggere quell'errore minore.

    
risposta data 09.10.2015 - 19:57
fonte

Leggi altre domande sui tag