Reputation: 23497
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 */}
}
How do I ensure that all the reader_func*()
functions do not assign value to num()
?
Addendum: In comments/answers, a few have suggested that I simply declare the field as a simple static int num;
. That will not work because it can potentially violate ODR
The reason I had to employ this slightly "odd" pattern is to not violate ODR
Also, the restriction here is that writer_func() will be called by other code, and I can't just preemptively call writer_func() to init the value
Upvotes: 3
Views: 188
Reputation: 2120
It's not especially elegant, but since you mention that writer_func
could potentially be called more than once, you could do something like:
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() */
}
Upvotes: 1
Reputation: 4169
Similar concept to George's suggestion, but with a neater/less sophisticated trade-off: wrap num()
in a read-only version and prevent (by extra class funkiness or by a static coding rule) use of num()
from 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 */}
};
Upvotes: 0
Reputation: 15524
If we're talking about a compile-time value, then what about making aNum
a class-scope static const
, e.g.:
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();
Upvotes: 0
Reputation: 3594
To ensure that you need to create a singleton class and allow modification only once:
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);
}
Output:
value changed to 10
value cannot be changed
Upvotes: 0
Reputation: 206607
One way to deal with it is to create a class that allows one time modification of the value and use an instance of the class.
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;
// ...
}
Upvotes: 0