【问题标题】:Does there exist the concept of set-once variables?是否存在设置一次变量的概念?
【发布时间】:2015-08-24 21:41:56
【问题描述】:

我想知道是否有人开发了一次设置变量的概念。也就是说,一个变量可能有一些默认值,但在程序执行期间只能设置一次。请注意,这与任何类型的常量都不同,因为常量是在程序执行之前设置的。

【问题讨论】:

  • 常量不一定要在程序执行前设置。但请选择一种语言。
  • 如果你在运行时设置它,那么它就是一个变量。没有办法解决它。至少在 C++ 中,您可以将其包装在一个具有适当保护和设置器/获取器的对象中,以强制执行一次性业务。
  • 寻找问题的解决方案。
  • C 和 C++ 都可以有 consts 具有运行时值。在声明之前不必知道该值。所有const 函数的输入都以这种方式工作。在 C++ 中,您甚至可以拥有 const 成员,这些成员可以在构造函数中初始化为动态值。
  • final 变量在 java 中做到这一点

标签: theory solid-principles


【解决方案1】:

对此没有预先打包的解决方案,但由于我们现在有once_flag,我们可以编写一个矫枉过正的解决方案,保证您只能调用operator= 一次:

template <typename T>
class SetOnce
{
public:
    SetOnce(T const& v)
    : val(v)
    { }

    SetOnce& operator=(T const& v) {
        std::call_once(flag, [=]{
            val = v;
        });
        return *this;
    }

    T get() const { return val; }

private:
    std::once_flag flag;
    T val;
};

int main() {
    SetOnce<int> so(4);
    std::cout << so.get() << '\n'; // 4
    so = 5;
    std::cout << so.get() << '\n'; // 5
    so = 6;
    std::cout << so.get() << '\n'; // still 5
}

不知道你会用这样的东西做什么,但 C++11 确实很酷。

【讨论】:

  • 好的,这很酷。 FWIW,这不是寻找问题的解决方案。
【解决方案2】:

在 C 或 C++ 中本机不存在这样的结构。

【讨论】:

    【解决方案3】:

    C++ 引用类型就是这样做的。

    一个参考变量,例如T &amp; ref,只能绑定一次(但在运行时,绑定到任何东西)。之后,指针表达式&amp;ref 实际上是一个常量,语言规则不允许它改变。

    【讨论】:

      【解决方案4】:

      也许可以使用一对函数来影响一个设置一次变量

      #include <assert.h>
      #include <stdlib.h>
      
      #define set_once_default 7
      typedef struct set_once_S set_once_T;
      
      set_once_T *value = NULL;
      
      int set_once_read(set_once_T *ptr) {
        if (ptr == NULL) return set_once_default;
        return *((int *) ptr);
      }
      
      void set_once_write(set_once_T *ptr, int value) {
        if (ptr == NULL) {
          ptr = malloc(sizeof value);
          assert(ptr);
          *((int *) ptr) = value;
        }
      }
      

      如果需要一个非全局的set_once_T,代码将需要free() 它超出范围。

      【讨论】:

        猜你喜欢
        • 2016-09-15
        • 2021-01-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-05
        • 2013-02-01
        • 2013-12-15
        • 1970-01-01
        相关资源
        最近更新 更多