在Cocos2Dx中实现Singleton的正确方法

Correct way to implement Singleton in Cocos2Dx

本文关键字:方法 Singleton Cocos2Dx 实现      更新时间:2023-10-16

目前我使用的方法是:

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

通过这种方式,我可以使用Singleton写作中的一种方法:

Singleton::getInstance.getData();

这似乎是阅读大量C++11教程的正确方式。但是通过阅读cocos-Director的单例代码(还有FileUtils等),我发现cocos使用了另一种方法:

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

用这种方法我必须写:

Singleton::getInstance->getData();

因为指针*getInstance而不是引用&getInstance

我认为差异很大,但我不知道一种方法是正确的,另一种方法不是。

请帮我理清这个概念。

在我看来,最好的单例是以值类型的形式呈现的,带有隐藏的单例实现。

这意味着您可以像传递任何其他对象一样传递singleton。

这反过来意味着,如果您稍后改变主意,并且singleton实际上需要成为一个普通对象,则不需要更改任何代码。

这也意味着您的singleton对象可以参与ADL和标记调度。

例如:

#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;
}

预期输出:

5
10
15
20
25