我有一些小的仅限标题的库(仅限标题的部分很重要)。在初始版本中,我在其中定义的类中有一些静态成员。直到后来(当我在一个更大的项目中使用它们时)我才发现静态成员会违反ODR。我想让它们只保留头文件,因此在一个单独的.cpp文件中定义静态成员是不可能的。一个众所周知的解决方案是为每个静态成员使用 Meyers singleton 函数局部静态变量(如建议的那样,here)。
这一切都很好,但由于我希望单例表现得像一个成员变量,我希望能够使用setter和getter来获取和设置值。但是,对于 Meyers singletons 函数本地静态变量的getter和setter是什么样的呢?我无法找到解决该特定问题的任何方法。
澄清一下,这些是要求:
编辑1:
我想解释为什么你可能需要这个。
我提到的库中的静态变量定义了某些参数的默认值。但是,我想让用户在程序开头设置默认值,而不是硬编码这些默认值,这样他们就不必在每次调用成员函数或构造一个函数时手动传递值。新实例。
此外,虽然我同意在此处提供的示例中使用术语“Meyers singleton”具有误导性(我只是使用int
值),但没有什么能阻止您使用此范例您只需要单个实例的自定义类。在这种情况下,“Meyers singleton”一词是合理的。
编辑2:
这与在C ++ 17中引入inline static
变量有点无关,但是我会把它留给那些没有选择使用C ++ 17的人。
答案 0 :(得分:5)
#include <iostream>
class Foo
{
private:
static int& val()
{
static int v = 0;
return v;
}
public:
Foo()
{
set_val(14);
}
Foo(const int _v)
{
set_val(_v);
}
// The setter uses the fact that val()
// returns a non-const reference,
// so we can assign to it.
static void set_val(const int _v)
{
val() = _v;
}
// A true getter.
// Returns const int&, so we cannot assign to it.
static const int& get_val()
{
return val();
}
};
int main(void)
{
std::cout << "val is " << Foo::get_val() << "\n";
Foo f1; // Set the value implicitly via an object constructor
std::cout << "val is " << Foo::get_val() << "\n";
Foo f2(5); // Set the value explicitly via an object constructor
std::cout << "val is " << Foo::get_val() << "\n";
Foo::set_val(42);
std::cout << "val is " << Foo::get_val() << "\n";
// Foo::get_val() = 4; // Doesn't compile, as required
return 0;
}
输出:
val is 0
val is 14
val is 5
val is 42
通过构造函数设置值可以(也可能应该)省略。我只想表明它可以做到。这是一个仅针对一个变量的代码,但比非静态成员的更多。
欢迎任何想法,意见和建议!