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(( 来初始化值
不是特别优雅,但是由于您提到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() */
}
处理它的一种方法是创建一个允许一次性修改值的类并使用类的实例。
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;
// ...
}
要确保需要创建单例类并仅允许修改一次,请执行以下操作:
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 changedn";
}
}
private:
static bool isSet;
static int value;
};
bool StaticContainer::isSet=false;
int StaticContainer::value;
int main()
{
StaticContainer::setValue(10);
StaticContainer::setValue(20);
}
输出:
值更改为 10
无法更改值
如果我们谈论的是编译时值,那么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();
与 George 的建议类似的概念,但有一个更整洁/不太复杂的权衡:将num()
包装在只读版本中,并防止(通过额外的类时髦或静态编码规则(使用来自reader_func*()
的num()
。
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 */}
};