Frage

Was ist der beste Weg, um einen Singleton in C zu erstellen? Eine gleichzeitige Lösung wäre schön.

Ich bin mir bewusst, dass C nicht die erste Sprache, die Sie für einen Singleton verwenden würden.

War es hilfreich?

Lösung

Als erstes ist C für OO-Programmierung nicht geeignet. Sie würden den ganzen Weg kämpfen, wenn Sie tun. Zweitens Singletons sind nur statische Variablen mit einiger Verkapselung. So können Sie eine statische globale Variable verwenden. Allerdings globale Variablen haben in der Regel viel zu viele Übel mit ihnen verbunden sind. Sie könnten sonst eine Funktion lokale statische Variable verwenden, wie folgt aus:

 int *SingletonInt() {
     static int instance = 42;
     return &instance;
 }

oder ein smarter Makro:

#define SINGLETON(t, inst, init) t* Singleton_##t() { \
                 static t inst = init;               \
                 return &inst;                       \
                }

#include <stdio.h>  

/* actual definition */
SINGLETON(float, finst, 4.2);

int main() {
    printf("%f\n", *(Singleton_float()));
    return 0;
}

Und schließlich, denken Sie daran, dass Singletons meist missbraucht werden. Es ist schwierig, sie richtig zu machen, vor allem unter Multi-Threaded-Umgebungen ...

Andere Tipps

Sie brauchen nicht zu. C bereits globale Variablen hat, so dass Sie brauchen keine Arbeits um sie herum zu simulieren.

Es ist das gleiche wie die C ++ Version ziemlich viel. Gerade haben eine Funktion, die eine Instanz Zeiger zurückgibt. Es kann eine statische Variable innerhalb der Funktion sein. Wickeln Sie den Funktionskörper mit einem kritischen Abschnitt oder pthread mutex, je nach Plattform.

#include <stdlib.h>

struct A
{
    int a;
    int b;
};

struct A* getObject()
{
    static struct A *instance = NULL;

    // do lock here
    if(instance == NULL)
    {
        instance = malloc(sizeof(*instance));
        instance->a = 1;
        instance->b = 2;
    }
    // do unlock

    return instance;
};

Beachten Sie, dass Sie eine Funktion benötigen würden, um auch den Singleton frei. Vor allem, wenn es keine Systemressourcen greift, die nicht automatisch auf Prozessbeendigung freigegeben.

EDIT: Meine Antwort setzt der Singleton Sie erstellen etwas komplex ist und einen mehrstufigen Erstellungsprozess. Wenn es nur statische Daten ist, gehen Sie mit einem globalen wie andere vorgeschlagen haben.

Ein Singleton in C wird sehr komisch sein. . . Ich habe noch nie ein Beispiel für „objektorientierte C“, die besonders elegant aussahen gesehen. Wenn möglich, sollten Sie C ++ verwenden. C ++ ermöglicht es Ihnen, und wählen zu wählen, welche Funktionen Sie verwenden möchten, und viele Menschen nutzen sie nur als „besser C“.

Im Folgenden ist ein ziemlich typisches Muster für Lock-Free einmalige Initialisierung. Die InterlockCompareExchangePtr tauscht atomar in dem neuen Wert, wenn die vorherigen null ist. Dies schützt, wenn mehrere Threads versuchen, die Singleton zugleich zu erstellen, wird nur eine gewinnen. Die anderen werden ihre neu erstellte Objekt löschen.

MyObj* g_singleton; // MyObj is some struct.

MyObj* GetMyObj()
{
    MyObj* singleton;
    if (g_singleton == NULL)
    {
        singleton = CreateNewObj();

        // Only swap if the existing value is null.  If not on Windows,
        // use whatever compare and swap your platform provides.
        if (InterlockCompareExchangePtr(&g_singleton, singleton, NULL) != NULL)
        {
              DeleteObj(singleton);
        }
    }

    return g_singleton;
}

DoSomethingWithSingleton(GetMyObj());

Hier ist eine andere Perspektive: jede Datei in einem C-Programm ist effektiv eine Singleton-Klasse, die automatisch zur Laufzeit instanziiert wird und kann nicht unterklassiert werden

.
  • Globale statische Variablen sind private Klasse Mitglieder.
  • Globale nicht statisch sind öffentlich (nur erklären, sie in irgendeiner Header-Datei mit extern).
  • Statische Funktionen sind private Methoden
  • Non-statische Funktionen sind die öffentlichen.

Geben Sie alles, was eine richtige Vorsilbe und jetzt können Sie my_singleton_method() anstelle von my_singleton.method() verwenden.

Wenn Ihr Singleton ist komplex Sie eine generate_singleton() Methode es zu initialisieren, vor dem Gebrauch schreiben können, aber dann müssen Sie alle andere öffentliche Methoden sicher, ob es genannt wurde und Fehler aus, wenn nicht.

Just do

void * getSingleTon() {
    static Class object = (Class *)malloc( sizeof( Class ) );
    return &object;
}

, die auch in einer Umgebung mit gemeinsamer Zugriff funktioniert.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top