确保静态成员最多设置一次(C ++)

时间:2018-01-25 22:36:35

标签: c++ static-initialization

class Foo {
   public:
     static int& num() {
          static int aNum = 0; // initial value
          return aNum;
     }

     static void writer_func() { /* ... do stuff and assign a value to num() */ }

     // a bunch of functions that "read" num()
     static void reader_func1() { /* uses num() in read-only mode */}
     static void reader_func2() { /* uses num() in read-only mode */}

}

如何确保所有reader_func*()函数都没有为num()赋值?

附录:在评论/答案中,有些人建议我只是将字段声明为简单的static int num;。这不起作用,因为它可能违反ODR

我必须使用这种略微“奇怪”模式的原因是不违反ODR

另外,这里的限制是writer_func()将被其他代码调用,我不能只是抢先调用writer_func()来初始化值

5 个答案:

答案 0 :(得分:1)

它并不是特别优雅,但是既然你提到writer_func可能不止一次被调用,你可以做类似的事情:

class Foo {
public:
    static const int& num();

    static void writer_func();

    // a bunch of functions that "read" num()
    static void reader_func1() { /* uses num() in read-only mode */}
    static void reader_func2() { /* uses num() in read-only mode */}

};

class Num {
    static int& num() {
        static int aNum = 0; // initial value
        return aNum;
    }
    friend const int& Foo::num();
    friend void Foo::writer_func();
};

const int& Foo::num() {
    return Num::num();
}

void Foo::writer_func() {
    /* ... do stuff and assign a value to num() */ 
}

答案 1 :(得分:0)

处理它的一种方法是创建一个允许一次修改值并使用类实例的类。

class OneTimeWrite
{
   public:

      OneTimeWrite() : value_(0), isset_(false) {}

      int get() const { return value_; };

      void set(int v)
      {
         if ( isset_ )
         {
            throw std::runtim_error("Value must not be set more than once.");
         }

         isset_ = true;
         value_ = val;
      }

   private:

      int value_;
      bool isset_;
}

class Foo
{
   public:
     static OneTimeWrite aNum;

     // ...    
}

答案 2 :(得分:0)

确保您需要创建单例类并且只允许修改一次:

class StaticContainer
{
public:
    static void setValue(int val){
        if (!isSet){
             isSet=true;
             value=val;
             std::cout<<"value changed to "<<val<<std::endl;
        }
        else{
            std::cout<<"value cannot be changed\n";    
        }
    }
private:
    static bool isSet;
    static int value;
};

bool StaticContainer::isSet=false;
int StaticContainer::value;
int main()
{
    StaticContainer::setValue(10); 
    StaticContainer::setValue(20);     
}

输出:

  

值更改为10

     

值无法更改

答案 3 :(得分:0)

如果我们在讨论编译时的价值,那么如何让aNum成为范围static const,例如

class Foo {
public:
    static const int aNum;

    static const int& num() {
        return aNum;
    }

    static int writer_func() { /* ... do stuff and return a value, e.g.: */ return 1; }

    // a bunch of functions that "read" num()
    static void reader_func1() { /* uses num() in read-only mode */}
    static void reader_func2() { /* uses num() in read-only mode */}
};

const int Foo::aNum = Foo::writer_func();

答案 4 :(得分:0)

George's建议相似的概念,但更简洁/更复杂的权衡:将num()包装在只读版本中并防止(通过额外的类funkiness或静态编码规则)使用num()中的reader_func*()

class Foo {
   public:
     static int& num() {
          static int aNum = 0; // initial value
          return aNum;
     }

     static int num_ro() {
          int &aNum = num();
          return aNum;
     }

     static void writer_func() { /* ... do stuff and assign a value to num() */ }

     // a bunch of functions that "read" num()
     static void reader_func1() { /* uses num_ro() in read-only mode */}
     static void reader_func2() { /* uses num_ro() in read-only mode */}

};