c++ 在只有头的库中为静态成员变量提供合适的setter和getter

a14dhokn  于 2023-04-08  发布在  其他
关注(0)|答案(1)|浏览(84)

我有几个小的只有头的库在最初的版本中,我在其中定义的类中有一些静态成员。(当我在一个更大的项目中使用它们时)静态成员会违反ODR。我想让它们只保留头,一个众所周知的解决方案是为每个静态成员使用Meyers单例函数局部静态变量(如建议的那样,例如here)。
这很好,但由于我希望单体像成员变量一样,我希望能够使用setter和getter来获取和设置值。但是Meyers单体函数局部静态变量的getter和setter是什么样子的?我还没有找到任何解决方案。
为了澄清,这些是要求:

  • 我希望静态成员变量的行为在只包含头的库中(因此我不能将定义放在.cpp文件中)
  • 我想要一个getter,它是一个getter only(我不应该通过赋值给getter返回的引用来修改值)
  • 我还希望能够通过专用的setter修改值。

编辑1:
我想解释一下为什么你需要这个。
我提到的库中的静态变量为一些参数定义了default值。然而,我不想硬编码这些默认值,而是想给予用户在程序开始时设置默认值,这样他们就不必在每次调用成员函数或构造新示例时手动传递值。
此外,尽管我同意在这里提供的示例中使用术语“Meyers singleton”是误导性的(我只是使用了一个int值),但没有什么可以阻止您将这种范式用于您只想要一个示例的自定义类。在这种情况下,“Meyers singleton”术语将是合理的。
编辑2:
随着C17中inline static成员的引入,这已经变得有些无关紧要了,但我将把它留给那些没有选择使用C17的人。

gmxoilav

gmxoilav1#

解决方案

#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

通过构造函数设置值可以(也许应该)被省略。我只是想证明这是可以做到的。这是一个变量的大量代码,但不是 * 那么多 * 比一个非静态成员。
欢迎大家提出任何想法、意见和建议!

相关问题