C ++中的单例习语

时间:2017-10-05 12:56:33

标签: c++ singleton

我想将代码从自定义语言转换为C ++。对于单例模式,我看到至少2种简单的翻译方式。

1:

namespace Singleton 
{
    int a, b; 
    int Function() 
    {
        return a+b; 
    }
}

int test = Singleton::Function(); 

2:

struct Singleton 
{
    int a, b; 
    int Function() 
    {
        return a+b; 
    }
} Singleton; //<-- The only instance

int test = Singleton.Function(); 

我知道概念上这些是等价的。我不是在寻找防止实例化/定义分离的封装/保护措施,因为这是转换,我不关心美学甚至代码长度。

但我想知道:这些总是会严格生成相同的程序集吗?我倾向于选择第二个,因为在结构中我可以声明以我想要的任何顺序互相引用的方法:

struct Singleton 
{
    int a, b; 
    int Function2() 
    {
        return Function() + 1; 
    }
    int Function() 
    {
        return a+b; 
    }
} Singleton;

int test = Singleton.Function2(); 

如果我使用命名空间,Function()应该是未声明的标识符。

那么,我是否有任何实际的理由要进入名称空间?在编译完成后,结构的单个实例是否总是或根本具有相同的含义?

1 个答案:

答案 0 :(得分:3)

他们几乎肯定会生成相同的程序集。在命名空间的情况下,Function接受零参数并访问两个全局变量;在struct的情况下,Function采用隐藏的this指针并通过它引用两个变量。

然而,性能差异很可能无关紧要,因此组装是否相同并不重要。

真正的问题是你是否想在两个翻译单元(.cpp文件)之间共享这个单例。如果你这样做,我会稍微偏爱名称空间版本,因为语言保证只有一个,而对于结构,你可能会意外地写struct Singleton Singleton2;并最终得到其中两个。

如果单例是单个.CPP的本地,那么你不需要命名结构:

struct // nameless struct.
{
    int a, b; 
    int Function() 
    {
        return a+b; 
    }
} Singleton; //<-- The only instance

int test = Singleton.Function(); 

最后的想法:还有另一个选项(几乎与命名空间选项相同):

struct Singleton 
{
    static int a, b; // All members must be static.
    static int Function() 
    {
        return a+b; 
    }
    Singleton() = delete;  // Prevent creating any instances.
};
Singleton::a;  // Must define the static members.
Singleton::b;


int test = Singleton::Function(); 

这允许以任意顺序声明函数,并且可以在文件之间共享。