2016-07-28 9 views
3

Ich möchte eine statische Elementvariable im Konstruktor einer bestimmten Instanz initialisieren. Ist das eine schlechte Idee?Initialisieren statischer Member innerhalb des Konstruktors einer Instanz

Die Situation ist wie folgt. Ich habe eine statische Elementvariable, die alle Instanzen dieser Klasse teilen sollten. Normalerweise würde ich nur einen statischen Initialisierer verwenden. Aber ich habe nicht die notwendigen Informationen, um das statische Objekt zu konstruieren, bis der Konstruktor aufgerufen wird. Aber natürlich möchte ich nicht jedes Mal, wenn der Konstruktor aufgerufen wird, ein neues Objekt erstellen, also möchte ich so etwas machen.

class Foo 
{ 
    static Bar * bar; 
    Foo(Xyz xyz); 
}; 

Bar * Foo::bar = nullptr; 

Foo::Foo(Xyz xyz) 
{ 
    if (Foo::bar == nullptr) 
    { 
     // initialize static bar 
     Foo::bar = new Bar(xyz); 
    } 
} 

ich natürlich wissen xyz migth für verschiedene Anrufe an den Konstruktor Foo unterschiedlich sein. Das ist mir egal.

Ist das schlechte Software-Design? Ich fühle mich etwas komisch, ein statisches Objekt im Konstruktor zu initialisieren. Aber es ist nicht so anders als das Singleton Designmuster. Also vielleicht ist es ok?

EDIT

Danke für die Kommentare Jungs. Es scheint, dass die Leute kein Fan dieses Designs sind. Ich werde es so ändern, dass ich ein Bar einmal vor der allerersten Instanz von Foo erstelle und einen Bar * als Parameter in Foo 's Konstruktor übergebe. Jede Foo wird einen Zeiger auf eine Bar haben, und ich werde sicherstellen, dass alle Foo s alle auf die gleiche Bar zeigen. Ist das besser?

+1

Sie beachten, dass Sie nicht Initialisierung tun. Sie werden Aufgabe tun. – NathanOliver

+0

Wie erhalten Sie den Wert, der für _initialization_ verwendet werden sollte? Ist es nur zur Laufzeit verfügbar? BTW Sie Probe wird nicht kompilieren. –

+3

Einzelgewinde sieht OK aus. Multi-Thread-Race-Zustand. –

Antwort

1

Ist das schlechte Software-Design?

In der Regel würde es ja so sein, ja. Es gibt viele Gründe, warum das Singleton Pattern oder statische Variablen auf diese Weise als schlechtes Design angesehen wird.


Aber es ist nicht so verschieden von dem Singleton-Entwurfsmuster. Also vielleicht ist es ok?

Wenn Sie wirklich, dass ein Singleton Pattern machen wollen Sie lieber Scott Meyer's technique verwenden sollten:

class Foo 
{ 
    static Bar* bar(Xyz xyz) { 
     static Bar barInstance(xyz); 
     return &barInstance; 
    } 
    Foo(Xyz xyz) : xyz_(xyz) {} 

    void baz() { 
     Bar* b = bar(xyz_); 
     // use b ... 
    } 

private: 
    Xyz xyz_; 
}; 

Dieser Code wird Thread-sicher sein, und vermeidet die Notwendigkeit eines nullptr zu überprüfen.


Obwohl Bar sollte eine Singleton auf seine eigene ist dann bilden, und verwenden Sie es in Foo bei Bedarf:

class Bar { 
public: 
    static Bar& getInstance(Xyz xyz) { 
     static Bar barInstance(xyz); 
     return &barInstance; 
    } 

private: 
    Bar(Xyz xyz) : xyz_(Xyz) {} 
    Bar(const Bar&) delete; 
    Bar(Bar&&) delete; 
    Bar& operator=(const Bar&) delete; 
    Bar& operator=(Bar&) delete; 

    Xyz xyz_; 
}; 

class Foo { 
public: 
    Foo(Xyz xyz) barRef(Bar::getInstance(xyz)) { 
             // ^^^ Notice 1st instance of Foo created 
             //  wins to create the Bar actually 
    } 
private: 
    Bar& barRef; 
}; 
+0

* "Aber ich habe nicht die notwendigen Informationen benötigt, um das statische Objekt zu konstruieren, bis der Konstruktor aufgerufen wird" * ... – Jarod42

+1

@ Jarod42 Das ist ein Indikator, das Design ist fehlerhaft, und 'Bar' sollte nicht in a sein statische Beziehung zu 'Foo'. Ich versuche nur, den Unterschied vom Singular-Muster zu erklären. –

Verwandte Themen