我想将代码从自定义语言转换为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()应该是未声明的标识符。
那么,我是否有任何实际的理由要进入名称空间?在编译完成后,结构的单个实例是否总是或根本具有相同的含义?
答案 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();
这允许以任意顺序声明函数,并且可以在文件之间共享。