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()来初始化值
答案 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 */}
};