纯标头库中静态成员变量的正确设置器和 getter
Proper setter and getter for static member variable in header-only library
我有几个小的仅标头库(仅标头部分很重要(。在最初的版本中,我在其中定义的类中有一些静态成员。直到后来(当我在一个更大的项目中使用它们时(,我才想到静态成员会违反 ODR。我想将它们保留为仅标头,因此在单独的.cpp文件中定义静态成员是不可能的。一个众所周知的解决方案是为每个静态成员使用Meyers 单例函数局部静态变量(例如,此处建议(。
这一切都很好,但是由于我希望单例的行为类似于成员变量,因此我希望能够使用setters和getter来获取和设置值。但是Meyers 单例函数局部静态变量的 getter 和 setter 是什么样的呢?我无法找到该特定问题的任何解决方案。
澄清一下,这些是要求:
- 我想要仅标头库中静态成员变量的行为(所以我不能将定义放在.cpp文件中(
- 我想要一个仅是 getter的 getter(我不应该能够通过分配给 getter 返回的引用来修改值(
- 我还希望能够通过专用的二传手修改值。
编辑1:
我想解释一下为什么您可能需要这个。
我提到的库中的静态变量定义了某些参数的默认值。但是,与其硬编码这些默认值,我想为用户提供在程序开始时设置默认值的选项,这样他们就不必在每次调用成员函数或构造新实例时手动传递值。
此外,尽管我同意在此处提供的示例中使用术语"Meyers singleton"具有误导性(我只是使用int
值(,但没有什么可以阻止您将此范例与自定义类一起使用您只需要一个实例。在这种情况下,"迈耶斯单身"一词是合理的。
编辑2:
随着 C++17 中引入inline static
成员,这变得有些无关紧要,但我会把它留给那些没有选择 C++17 的人。
解决方案
#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
通过构造函数设置值可以(并且可能应该(省略。我只是想表明这是可以做到的。这只是一个变量的大量代码,但并不比非静态成员多多少。
欢迎任何想法、意见和建议!
相关文章:
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 在C++/Linux中设置单调时钟的一些技巧
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 嵌套在类中时无法设置成员数据
- 需要帮助设置在C++中使用的Potrace
- 如何在自删除后将对象设置为nullptr
- 将指针设置为"nullptr"并不能防止双重删除?
- 如何通过 getter 函数删除矢量的元素?
- 如何在Ubuntu中使用cmake设置qt4
- ld:bind_at_load和-bitcode_bundle(Xcode设置ENABLE_bitcode=YES)不能
- 如何在boost beast http请求中设置http头
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 如何将这个C++哈希表转换为动态扩展和收缩,而不是使用硬设置的最大值
- 为什么文件名被设置为一个点,而不是在读取矢量中的文件名时
- 如何在24位SDL_Surface上设置像素的颜色
- std::设置自定义比较器
- 纯标头库中静态成员变量的正确设置器和 getter
- 使用 getter 设置私有变量
- 如何使用静态变量,使用自定义Getter和设置器在SWIG中扩展结构
- 使用参数的 getter 之一在 C++ 函数中设置另一个参数的值?