C++, statische vs. namespace vs. singleton
Ich schon lese viele Beiträge und Artikel alle über das Netz, aber ich konnte nicht finden eine definitive Antwort über dieser.
Ich habe einige Funktionen mit ähnlichen Zwecken, die ich haben will aus dem globalen Bereich. Einige von Ihnen müssen öffentlich, andere sollte privat sein (weil Sie nur Hilfsfunktionen für die "öffentlichen" sind).
Darüber hinaus habe ich nicht nur Funktionen, sondern auch die Variablen. Sie sind nur erforderlich, durch die "private" Helfer-Funktionen und sollte privat sein, auch.
Nun gibt es die drei Möglichkeiten:
- machen eine Klasse mit alles statisch (contra: Potenzial "Nicht aufrufen member-Funktion ohne Objekt" - nicht alles muss statisch sein)
- machen eine singleton-Klasse (contra: ich muss das Objekt)
- machen einen Namensraum (kein eigenes Stichwort -, warum sollte ich es in einem namespace, dann?)
Was wäre der Weg für mich? Möglichkeit der Kombination einiger dieser Möglichkeiten?
Dachte ich an etwas wie:
- macht ein singleton ist, die statische Funktionen verwenden die Hilfsfunktion des singleton-Objekt (ist das möglich? Ich bin noch innerhalb der Klasse, aber der Zugriff auf ein Objekt dieser Art)
- Konstruktor aufgerufen, am programm starten, initialisiert alles (-> sicherstellen, dass die Statik Zugriff auf die Funktionen der singleton-Objekt)
- Zugang zu den öffentlichen Funktionen nur durch MyClass::PublicStaticFunction()
Dank.
- Keine singletons verwenden, es sei denn, Sie wirklich brauchen, um (ie. fast nie). Eine gute Diskussion ist ibm.com/developerworks/webservices/library/co-single/index.html
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wie bereits angemerkt, ist die Verwendung von globalen Variablen ist generell schlecht, der Technik, es sei denn, absolut notwendig, natürlich (Zuordnung der hardware zum Beispiel, aber das passiert nicht oft).
Verstauen alles in einer Klasse ist etwas, was Sie tun würde, in einer Java-ähnlichen Sprache, aber in C++ können Sie nicht haben, um, und in der Tat die Verwendung von namespaces ist hier eine bessere alternative, wenn nur:
Hier ist eine typische Implementierung:
Den anonymen namespace versteckt in einer Quellcode-Datei ist eine erweiterte
private
Abschnitt: nicht nur, dass der client verwenden können, was drin ist, aber er sieht nicht einmal, es überhaupt (da es in der Quell-Datei) und damit nicht davon abhängig sind (das hat bestimmte ABI-und compile-time-Vorteile!)static
gibt es für Gestänge, in Erster Linie: das symbol ist dann nicht sichtbar außerhalb der übersetzungseinheit, in der Sie definiert ist, vermeidet Kollisionen. Auch Hinweise an den compiler, dass es muss nicht emittieren die Funktion code aus und vielleicht möchten Sie erwägen stärker inlining es. Übrigens, es verhindert auch, dass jemand, spähte in den source code von der Deklaration der Funktion so verwenden Sie es zu: um es zu verwenden müssen Sie irgendwie kontrollieren die binäre finden seine Adresse... wenn es überhaupt existiert (sprich, war nicht inlined).static
. Es gibt noch weitere Feinheiten (wrt. Spezialisierung/name look-up) sowie...Machen Sie es nicht ein singleton
Für öffentliche helper-Funktionen, die nicht direkt abhängig von diesen Variablen, machen Sie nicht-member-Funktionen. Es gibt nichts zu gewinnen, indem Sie Sie in eine Klasse.
Für den rest, steckte es in eine Klasse, die als normale nicht-statische member. Wenn Sie eine einzige Global verfügbare Instanz der Klasse, erstellen Sie dann eine (aber don ' T machen es ein singleton ist, wird nur eine Globale).
Sonst instanziieren Sie es, wenn nötig.
namespace
, aber vielleicht die Menschen kommen aus einem Java-hintergrund nicht.Den klassischen C Weg, dies zu tun ist, scheint das zu sein, was Sie wollen, ist, um die öffentlichen Deklarationen in eine header-Datei und die Implementierung in die source-Datei, so dass die Variablen und nicht-öffentliche Funktionen statisch. Sonst einfach umzusetzen, die es als Klasse - ich glaube, Sie machen ein bisschen einen Berg aus einem Maulwurfshügel hier.
static
diese Weise veraltet ist, in C++ zu Gunsten der anonymen namespaces. Sonamespace { int i; }
eher alsstatic int i;
Sonst, ja.static
mit drei komplett verschiedenen Bedeutungen albern. Aber ein Blick durch den C++0x draft, scheinen Sie entfernt zu haben, dass etwas. Also nevermind 🙂Was ist mit dem Schlüsselwort
static
im globalen Gültigkeitsbereich (was Zeug lokal auf die Datei) als Datenschutz-Ersatz?Ihrer Beschreibung nach sieht es aus wie Sie haben Methoden und Daten, interagieren mit jeder anderen hier, in anderen Worten, es klingt für mich wie Sie wirklich wollen, eine nicht-singleton-Klasse, um den Zustand zu verwalten und bieten Operationen auf diesem Zustand. Setzen Sie Ihre öffentlichen Funktionen wie das interface und alles andere privat.
Dann können Sie die Instanz(en) als notwendig, Sie müssen nicht sorgen zu machen über die init -, um-oder threading-Problemen (falls Sie eine haben pro thread), und nur clients, die Zugriff haben, ein Objekt zu betreiben, auf. Wenn Sie wirklich brauchen nur eins von diesen für das gesamte Programm, das Sie bekommen konnte, Weg sagen einen globalen Zeiger, das in
main
oder womöglich eineinstance
Methode, aber diese kommen mit Ihren eigenen Problemlagen.Denken Sie daran, dass die singleton-Instanz der singleton-Klasse ist eine gültige Instanz, so ist es durchaus in der Lage zu sein, die Empfänger von nicht-statische member-Funktionen. Wenn Sie setzen das singleton-factory als eine statische Funktion haben dann alle Ihre öffentlichen Funktionen wie öffentliche nicht-statische member-Funktionen und Ihre privaten Funktionen wie private nicht-statische member-Funktionen, jeder, der in der Klasse können auf die öffentliche Funktionalität durch den Aufruf einfach die singleton-factory-Funktion.
Ihnen nicht beschreiben, ob alle Funktionen, die Sie versuchen zu wickeln ist als verwandt zu rechtfertigen in der gleichen Klasse, aber wenn es ist, dieser Ansatz funktionieren könnte.
Wenn Sie einen "C-like" - Ansatz und verwenden nur top-level-Funktionen, können Sie Sie privat, indem Sie in die .cpp-Datei und nicht als die öffentlich-enthalten .h-Datei. Das sollten Sie auch machen Sie, statische (oder eine anonyme namespace), wenn Sie nehmen diesen Ansatz.