2016-03-30 5 views
0

Derzeit bin ich mit diesem Ansatz:korrekte Art und Weise Singleton in Cocos2Dx zu implementieren

class Singleton { 
public: 
    static Singleton &getInstance() { 
    static Singleton *instance = new Singleton(); 
    return *instance; 
    } 
void getData(); 

private: 
    Singleton() {} 
}; 

Auf diese Weise habe ich eine Methode aus Singleton Schreiben verwenden können:

Singleton::getInstance.getData(); 

Und dies scheint der richtige Weg eine Menge Tutorials für C++ 11 lesen. Aber das Lesen durch cocos Director Singleton-Code (auch FileUtils etc ..), habe ich gesehen, dass Cocos diesen anderen Ansatz verwendet:

class Singleton { 
public: 
    static Singleton *getInstance() { 
    instance = new Singleton(); 
    return instance; 
    } 
void getData(); 

private: 
    Singleton() {} 
    static Singleton *instance; 
}; 

Mit diesem Ansatz, den ich schreiben müssen:

Singleton::getInstance->getData(); 

Wegen der Zeiger * getInstance anstelle der Referenz & getInstance.

Ich denke, der Unterschied ist groß, aber ich weiß nicht, ob der eine Weg richtig ist und der andere nicht.

Bitte helfen Sie mir, dieses Konzept zu sortieren.

+0

Singletons sind nicht in C++ benötigt. Verwenden Sie eine Funktion, die einen Verweis auf ein statisches Objekt zurückgibt. –

+0

danke @RichardHodges können Sie mich bitte etwas spezifisch verknüpfen? Ich wollte ein Singleton, um ein gemeinsames Spieldatenobjekt zu erstellen, und ich dachte, es wäre der richtige Weg. –

Antwort

0

Meiner Ansicht nach wird der beste Singleton als Werttyp mit einer verdeckten Singleton-Implementierung dargestellt.

Dies bedeutet, dass Sie das Singleton wie jedes andere Objekt weitergeben können.

Dies wiederum bedeutet, dass wenn Sie später Ihre Meinung ändern und das Singleton eigentlich ein normales Objekt sein muss, Sie keinen Code ändern müssen.

Es bedeutet auch, dass Ihr Singleton-Objekt an ADL und Tag-Dispatching teilnehmen kann.

zB:

#include <iostream> 

// only this goes in the header file 
struct my_thing 
{ 
    // public interface 
    int do_or_get_something(int arg); 

private: 
    struct impl; 
    static impl& get_impl(); 

}; 

// this goes in the cpp file 
struct my_thing::impl 
{ 
    int do_or_get_something(int arg) 
    { 
     // for demo purposes 
     return counter += arg; 
    } 

    int counter = 0; // for demo purposes 
}; 

my_thing::impl& my_thing::get_impl() 
{ 
    // create first time code flows over it - c++ standard 
    // thread safe in c++11 - guarantee 
    static impl instance {}; 
    return instance; 
} 

// implement public interface in terms of private impl 
int my_thing::do_or_get_something(int arg) 
{ 
    return get_impl().do_or_get_something(arg); 
} 

// test the concept 
int main() 
{ 
    auto one_thing = my_thing(); 
    std::cout << one_thing.do_or_get_something(5) << std::endl; 
    std::cout << one_thing.do_or_get_something(5) << std::endl; 

    auto another_thing_but_really_same = my_thing(); 
    std::cout << another_thing_but_really_same.do_or_get_something(5) << std::endl; 

    std::cout << my_thing().do_or_get_something(5) << std::endl; 
    std::cout << one_thing.do_or_get_something(5) << std::endl; 

} 

erwartete Ausgabe:

5 
10 
15 
20 
25 
+0

Vielen Dank für dieses Beispiel, eine andere Sichtweise ist immer willkommen. Aber bitte kannst du mir in meinen Beispielen die Unterschiede zwischen Singleton mit Zeiger und mit Referenz erklären? –

+0

@DarioDP Es gibt keinen wirklichen Unterschied zwischen der Ponter- und der Referenzimplementierung. Der wirkliche Unterschied liegt darin, ob das Singleton-Objekt statisch zugewiesen oder mit neuem erstellt wird. Die statische Zuweisungsroute ist besser, da das Objekt am Programmende freigegeben wird. –

+0

@DarioDP Vorsicht beim Lernen von C++ aus Büchern und Tutorials. Die Autoren wissen nicht alle, wovon sie reden. Bitte studieren Sie mein Beispiel, referenzieren Sie mein Denken mit dem C++ Standard. Es ist nicht "ein Standpunkt", es ist korrekt :-) http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4527.pdf –