【问题标题】:Correct way to implement Singleton in Cocos2Dx在 Cocos2Dx 中实现 Singleton 的正确方法
【发布时间】:2016-03-30 14:01:55
【问题描述】:

目前我正在使用这种方法:

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

我觉得差别很大,但不知道是不是一种方式正确,另一种方式不正确。

请帮我理清这个概念。

【问题讨论】:

  • c++ 中不需要单例。使用返回对静态对象的引用的函数。
  • 谢谢@RichardHodges 能给我一些具体的链接吗?我想要一个用于创建共享游戏数据对象的单例,我认为这是正确的方法。

标签: c++ c++11 singleton cocos2d-x


【解决方案1】:

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

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

这反过来意味着如果你以后改变主意,而单例实际上需要是一个普通的对象,你不需要更改任何代码。

这也意味着你的单例对象可以参与 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

【讨论】:

  • 感谢您提供此示例,始终欢迎其他观点。但是请你在我的例子中解释一下单例与指针和引用的区别?
  • @DarioDP ponter 和参考实现之间没有真正的区别。真正的区别在于单例对象是静态分配的还是用new创建的。静态分配路线更好,因为对象将在程序结束时被释放。
  • @DarioDP 从书籍和教程中学习 c++ 时要小心。作者们并不都知道他们在说什么。请研究我的示例,将我的想法与 c++ 标准交叉引用。这不是“观点”,是正确的:-) open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4527.pdf
  • 非常感谢@RichardHodges
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多