Domanda

Mi piace usare le funzioni statiche in C++ come modo per classificarle, come fa C#.

Console::WriteLine("hello")

È un bene o un male?Se le funzioni vengono utilizzate spesso, immagino non abbia importanza, ma in caso contrario mettono sotto pressione la memoria?

Che dire static const?

È stato utile?

Soluzione

ma è un bene o un male?

Il primo aggettivo che mi viene in mente è “inutile”.C++ ha funzioni e spazi dei nomi gratuiti, quindi perché dovresti renderli funzioni statiche in una classe?

L'uso di metodi statici in classi non istanziabili in C# e Java è una soluzione alternativa perché quei linguaggi non hanno funzioni libere (cioè funzioni che risiedono direttamente nel namespace, piuttosto che come parte di una classe).Il C++ non ha questo difetto.Usa semplicemente uno spazio dei nomi.

Altri suggerimenti

Sono favorevole all'uso statico funzioni.Questi hanno senso soprattutto se organizzati in moduli (static class in C#).

Tuttavia, il momento quelle funzioni necessitano di un qualche tipo di dati esterni (non const in fase di compilazione), quindi quella funzione dovrebbe essere resa un metodo di istanza e incapsulata insieme ai suoi dati in una classe.

In poche parole:funzioni statiche ok, dati statici pessimi.

Chi dice che le funzioni statiche possono essere sostituite dai namespace si sbaglia, ecco un semplice esempio:

class X
{
   public:
   static void f1 ()
   {
      ...
      f2 ();
   }

   private:
     static void f2 () {}
};

Come puoi vedere, public static function f1 chiama un'altra funzione statica, ma privata f2.

Questa non è solo una raccolta di funzioni, ma una raccolta intelligente con i propri metodi incapsulati.Gli spazi dei nomi non ci darebbero questa funzionalità.

Molte persone usano il modello "singleton", solo perché è una pratica comune, ma in molti casi è necessaria una classe con diversi metodi statici e un solo membro dati statico.In questo caso non è affatto necessario un singleton.Chiamando anche il metodo instance() è più lento rispetto al semplice accesso diretto alle funzioni/membri statici.

Utilizza gli spazi dei nomi per creare una raccolta di funzioni:

namespace Console {
    void WriteLine(...) // ...
}

Per quanto riguarda la memoria, le funzioni utilizzano la stessa quantità all'esterno di una funzione, come funzione membro statica o in uno spazio dei nomi.Questo è:nessuna memoria oltre al codice stesso.

Uno dei motivi specifici per cui i dati statici non sono validi è che il C++ non fornisce garanzie sull'ordine di inizializzazione degli oggetti statici in diverse unità di traduzione.In pratica ciò può causare problemi quando un oggetto dipende da un altro in un'unità di traduzione diversa.Scott Meyers ne parla nel punto 26 del suo libro More Effective C++.

Sono d'accordo con Frank qui, non c'è un problema con le funzioni statiche (globali) (ovviamente a condizione che siano organizzate).I problemi iniziano a insinuarsi davvero solo quando le persone pensano "oh, amplierò solo un po' il campo di applicazione di questi dati".Pendio scivoloso :)

Per metterlo davvero in prospettiva.. Programmazione Funzionale ;)

Il problema con le funzioni statiche è che possono portare a una progettazione che interrompe l'incapsulamento.Ad esempio, se ti ritrovi a scrivere qualcosa del tipo:

public class TotalManager
{
    public double getTotal(Hamburger burger)
    {
        return burger.getPrice() + burget.getTax();
    }
}

...allora potresti dover ripensare il tuo design.Le funzioni statiche spesso richiedono l'uso di setter e getter che ingombrano l'API di una classe e rendono le cose più complicate in generale.Nel mio esempio, potrebbe essere meglio rimuovere i getter di Hamburger e spostare semplicemente la classe getTotal() nello stesso Hamburger.

Tendo a creare classi costituite da funzioni statiche, ma alcuni dicono che il "modo giusto" per farlo è solitamente utilizzare invece gli spazi dei nomi.(Ho sviluppato le mie abitudini prima che il C++ avesse gli spazi dei nomi.)

A proposito, se hai una classe composta solo da dati e funzioni statici, dovresti dichiarare che il costruttore è privato, quindi nessuno tenta di crearne un'istanza.(Questo è uno dei motivi per cui alcuni sostengono di utilizzare gli spazi dei nomi anziché le classi.)

Per l'organizzazione, utilizzare gli spazi dei nomi come già indicato.

Per i dati globali mi piace usare il file singleton pattern perché aiuta a risolvere il problema dell'ordine di inizializzazione sconosciuto degli oggetti statici.In altre parole, se si utilizza l'oggetto come singleton è garantito che venga inizializzato quando viene utilizzato.

Assicurati inoltre che le tue funzioni statiche siano senza stato in modo che siano thread-safe.

Di solito utilizzo le statistiche solo insieme al sistema degli amici.

Ad esempio, ho una classe che utilizza molte funzioni di supporto interne (inline) per calcolare cose, comprese le operazioni su dati privati.

Ciò, ovviamente, aumenta il numero di funzioni dell'interfaccia della classe.Per sbarazzarmene, dichiaro una classe helper nel file .cpp delle classi originali (e quindi invisibile al mondo esterno), la rendo amica della classe originale e quindi sposto le vecchie funzioni helper nel membro statico (inline) funzioni della classe helper, passando la vecchia classe per riferimento oltre ai vecchi parametri.

Ciò mantiene l'interfaccia snella e non richiede un lungo elenco di funzioni gratuite per gli amici.Anche l'inlining funziona bene, quindi non sono completamente contrario all'elettricità statica.(Lo evito il più possibile, ma usarlo così mi piace farlo.)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top