Quando entrano in uso le "funzioni statiche"?

22

OK, ho imparato che cos'è una funzione statica, ma non vedo ancora perché sono più utili delle funzioni dei membri privati. Potrebbe essere una specie di domanda newb-ish, ma perché non sostituire semplicemente tutte le funzioni dei membri privati con funzioni statiche?

    
posta Dark Templar 07.10.2011 - 19:57
fonte

15 risposte

22

Supponendo che tu stia utilizzando OOP , usa le funzioni statiche quando non dipendono da alcun membro della classe . Possono comunque essere privati, ma in questo modo vengono ottimizzati in quanto non dipendono da alcuna istanza dell'oggetto correlato.

Oltre a quanto sopra, trovo le funzioni statiche utili quando non si desidera creare un'istanza di un oggetto solo per eseguire una funzione pubblica su di esso. Questo è principalmente il caso per le classi di helper che contengono funzioni pubbliche per fare un po 'di lavoro ripetitivo e generale, ma non è necessario mantenere alcun stato tra le chiamate.

    
risposta data 07.10.2011 - 20:15
fonte
7

Cercando una spiegazione più semplice di quella precedente (piuttosto buone).

Un oggetto è codice + dati normalmente. Viene utilizzato un metodo statico quando si ha a che fare solo con la parte "codice" (non ci sono dati / stato mantenuto).

    
risposta data 07.10.2011 - 21:14
fonte
5

Perché non richiedono un'istanza e possono essere pubblici. Supponiamo che tu abbia bisogno di una funzione per ottenere il massimo comun denominatore (GCD, molto utile per le classi di frazioni, e sì, questo è solo un semplice esempio). Non ha senso creare una classe di oggetti il cui unico scopo è quello di avere un puntatore this che non è necessario né utilizzare in gcd . Quindi utilizzi un metodo statico per esso, idealmente sulla classe che utilizza effettivamente il GCD (ad esempio nella classe frazione).

Di coures se ci sono solo metodi statici, stai facendo OOP errato e dovresti passare a fare effettivamente OOP o usare un linguaggio più appropriato al tuo paradigma.

    
risposta data 07.10.2011 - 20:18
fonte
2

Li uso come funzioni di supporto per le attività comuni, ad esempio:

  • Conversione di gradi in radianti (e viceversa);
  • Hashing a string;
  • Conversione da un enum a qualcos'altro (in questo progetto sto lavorando, si comportano come una tabella hash);

La maggior parte dei miei file che raggruppano funzioni statiche hanno il suffisso Helper, il che significa che è ciò che fanno, mi aiutano ad andare da qualche parte più velocemente.

    
risposta data 07.10.2011 - 20:23
fonte
2

Per quanto riguarda il metodo statico:

Static methods neither require an instance of the class nor can they implicitly access the data (or this, self, Me, etc.) of such an instance.[1]

Esempi di quando i metodi statici sono utili:

  • Metodi globali / di supporto
  • Ottenere risultati di query da una classe del modello di dati (chiamando un SP)

Basta usarli solo dove appropriato.

  1. Se ti ritrovi a copiare gli stessi metodi in più oggetti considera di rendere statico il metodo in modo da poter seguire DRY.
  2. Utilizza metodi statici se non hai bisogno di un'istanza di un oggetto (non stai lavorando su e le variabili di istanza dell'oggetto)

Se molti dei tuoi dati sono al di fuori degli oggetti e vengono elaborati tramite metodi statici, il tuo codice non è orientato agli oggetti e potrebbe essere difficile da mantenere.

    
risposta data 07.10.2011 - 21:54
fonte
1

Statico e privato sono infatti ortogonali: un metodo può essere statico, o privato, o nessuno, o entrambi.

Statico e non statico (a.k.a. "metodi di istanza") indica se il metodo opera sulla classe stessa (statica) o su una particolare istanza (non statica). A seconda della lingua, puoi chiamare un metodo statico attraverso un'istanza, ma non puoi mai accedere all'istanza tramite un metodo statico (il che implica anche che non puoi chiamare metodi non statici all'interno di un metodo statico, semplicemente perché non hai this oggetto). Utilizzare metodi statici per implementare comportamenti concettualmente collegati alla classe, ma non "associare" a una particolare istanza. Un altro scenario in cui si potrebbe voler utilizzare metodi statici è quando si ha una funzione che opera su due istanze di una classe, e nessuno degli operandi merita uno stato privilegiato - ad esempio, supponendo di avere una classe Vector , e si desidera implementare Inoltre; il tuo metodo di addizione potrebbe essere chiamato a.Add(b) , ma Vector.Add(a, b) probabilmente ha più senso.

Privato e pubblico riguardano visibilità del metodo. È possibile accedere ai metodi privati solo nell'ambito della classe stessa, mentre i metodi pubblici sono accessibili da qualsiasi luogo. L'uso più importante di questo è l'incapsulamento: rendendo pubblici solo quei metodi e proprietà che sono assolutamente necessari al resto del codice per comunicare con la classe, limiti i punti in cui il codice esterno può introdurre problemi e previeni problemi all'interno la tua classe sanguinante nel resto del progetto.

Quindi, regola generale:

  • rende private tutte le funzioni membro, eccetto quelle che devono essere chiamate al di fuori della classe
  • crea tutti i metodi di istanza dei metodi, a meno che non abbiano senso anche se non esiste un'istanza della classe
risposta data 07.10.2011 - 22:13
fonte
0

Uso metodi statici sia in C ++ che in C # per le classi Utility, classi che non hanno dati di istanza, solo un modo per raggruppare una raccolta di metodi utili e correlati.

int count1 = DBUtil::GetCountOfSlackerEmployees();
int count2 = DBUtil::GetCountOfEmployedSlackers();
    
risposta data 07.10.2011 - 21:32
fonte
0

Supponendo che stai parlando di C ++ (non hai detto) e hai i termini giusti (cioè non intendo funzioni / metodi membro):

Anche una funzione membro privata deve ancora essere dichiarata nell'intestazione, il che significa che diventa effettivamente parte dell'API e dell'ABI della classe, anche se l'utente non può effettivamente chiamarla. Se aggiungi, modifichi o cancelli la funzione membro privata, stai forzando la ricompilazione di tutte le classi dipendenti (l'intestazione è cambiata, make non può saperlo meglio) e quando lo fai in una libreria, devi considerare la compatibilità per l'applicazione usando esso.

D'altra parte le funzioni statiche con scope del file non ricevono un simbolo pubblico, quindi puoi aggiungerle, modificarle o cancellarle a tuo piacimento e nulla oltre la singola unità di compilazione sarà mai influenzato.

    
risposta data 07.10.2011 - 22:05
fonte
0

In genere è necessario un main static per fungere da punto di ingresso per il programma. Potrebbe essere un po 'importante.

    
risposta data 07.10.2011 - 22:12
fonte
0

Una funzione statica (e diversi significati per quel termine in diverse lingue), non richiede alcuno stato che viene mantenuto tra le chiamate. Se è concettualmente strettamente legato a ciò che fa una classe, rendila una funzione di classe (come in una classe non un oggetto) o, in caso contrario, rendila una funzione globale (o di livello modulo, qualunque). Non appartiene a un oggetto se non ha bisogno dello stato dell'oggetto.

Se stai passando lo stato continuamente, non è una funzione stateless, stai solo facendo una funzione stateful con sintassi stateless. In quel caso, probabilmente appartiene all'oggetto chiamante, o forse un refactoring per allineare meglio lo stato e il comportamento è indicato.

    
risposta data 07.10.2011 - 23:09
fonte
0

"perché non sostituire semplicemente tutte le funzioni dei membri privati con funzioni statiche?"

... perché un membro privato può accedere ai dati dell'istanza mentre consente solo che si verifichi da chiamate effettuate all'interno di altre funzioni membro. La funzione statica può essere privata, ma non sarà in grado di modificare o fare riferimento a un'istanza della classe a meno che l'istanza non venga passata come parametro.

    
risposta data 08.10.2011 - 02:17
fonte
0

È strano come nessuno sia stato ancora in grado di dare una buona risposta. Non sono sicuro neanche di questo. Probabilmente dovresti prenderlo come un suggerimento che dovrebbero essere usati il meno possibile. Sono dopotutto procedurali piuttosto che OOP.

Ecco alcuni esempi:

In Obj-C, dove vengono chiamati metodi di classe, vengono comunemente usati come wrapper di allocazione in cui l'oggetto viene inserito nel lotto di conteggio di riferimento prima di essere restituito.

Un altro esempio di Obj-C è di registrare una nuova classe in una raccolta di classi. Supponiamo che tu abbia un set di classi che gestiscono ciascun tipo di file. Quando crei una nuova classe per un nuovo tipo di file, puoi registrarla alla raccolta (una variabile globale) utilizzando un metodo statico nella classe che determina il tipo di file.

In C ++ un altro uso che posso pensare è di rilevare gli errori in modo sommario. La tua funzione di costruzione non può fallire, tranne lanciando un'eccezione. È possibile impostare una variabile di istanza di errore, ma non è sempre appropriato. Invece puoi fare le parti che potrebbero fallire in un wrapper statico e quindi allocare e restituire il nuovo oggetto, o NULL in caso di fallimento.

    
risposta data 08.10.2011 - 12:33
fonte
0

Diciamo che vuoi calcolare il seno di qualcosa.

Senza statico:

Math math = new Math()
double y = math.sin(x)

Con statico:

double y = Math.sin(x)

Non ha senso rendere sin non-statico. È stateless e elabora solo l'input.

Le funzioni statiche non sono legate a oggetti particolari. Sono funzioni "generali" che sono indipendenti dallo stato interno dell'oggetto.

    
risposta data 08.10.2011 - 13:39
fonte
0

Tipo di ritardo qui, ma mi piacerebbe provare a creare una definizione precisa: le funzioni statiche sono funzioni che non possono o non possono fare riferimento a proprietà / metodi dell'istanza della classe contenente.

In alcune lingue, come C #, potrebbero esserci campi o proprietà statiche nelle classi statiche, quindi non è esatto dire che non sono usati per lo stato; una funzione statica potrebbe utilizzare lo stato statico (globale).

Fondamentalmente, si riduce a: le funzioni statiche, come qualsiasi cosa statica, sono utili quando ha senso che siano sempre disponibili senza dipendenza da istanze non statiche.

Le funzioni di supporto, come le funzioni matematiche, sono un esempio spesso attivato, ma ce ne sono altre.

Se la classe creata richiede che i dati siano immutabili, potrebbe avere senso creare funzioni statiche che includano un'istanza e passino una nuova istanza poiché l'istanza non può (o non dovrebbe) essere modificata. Le classi di stringhe, ad esempio, potrebbero avere funzioni statiche che contengono una stringa (o 2 o più) e passano una nuova stringa.

Un altro motivo potrebbe essere che esiste una classe che mantiene uno stato globale o dati di qualche tipo. Potrebbero esserci funzioni statiche che funzionano con le proprietà o campi statici in quella classe statica.

    
risposta data 14.10.2011 - 02:20
fonte
0

Vorrei segnalare un altro uso di static f ().

link

Si riduce a questo: le funzioni static consentono di creare "Costruttori denominati", ovvero si assegna la propria funzione statica con un nome adatto e autoreferenziale, e questa funzione statica chiama uno dei costruttori (poiché i costruttori hanno nomi identici e puoi averne molti, diventa difficile distinguerli)

    
risposta data 22.08.2013 - 20:47
fonte

Leggi altre domande sui tag