I have the following code:
Doc header file
class CMyDoc
{
public:
class Suspender
{
friend class CMyDoc;
static bool m_suspending;
inline static const bool IsSuspending() { return m_suspending; }
public:
Suspender()
{
m_suspending = true;
}
~Suspender()
{
m_suspending = false;
}
};
}
Doc source file
Static variable initialization:
bool CMyDoc::Suspender::m_suspending = false;
Check if it is on the "not allowed" to do things state, and if so, don't do them:
void CMyDoc::SomeMethod()
{
if (!Suspender::IsSuspending())
DoThings();
}
Somewhere where I want to run some code on the "not allowed" state
Declare a variable of the Suspender type. Automatically will put on the "not allowed state" on the declaration. But the greatest benefit is it will return itself back to the "allowed" state when the stack frame ends, as it passes on the s variable's destructor.
void CMyView::DoSomething()
{
CMyDoc::Suspender s;
((CMyDoc*) GetDocument())->SomeMethod();
}
QUESTIONS:
What is the name of the pattern?
Am I doing it in the most correct way? Can I avoid to have a static variable?
No, I don't think you are doing it in the most correct way, and because of the flaw in it I don't think its really RAII either.
The flaw I believe is there can be demonstrated without threads.
void SomeViewMethod()
{
Suspender s1;
((CMyDoc*) GetDocument())->SomeMethod();
}
SomeOtherViewMethod()
{
Suspender s2;
((CMyDoc*) GetDocument())->SomeMethod();
SomeViewMethod();
// this looks like suspender s2 should be suspending the next call...
// but when the s1 inside SomeViewMethod went out of scope it turned off suspending
((CMyDoc*) GetDocument())->SomeMethod();
}
This particular issue could be addressed by replacing the bool with an int to allow nested suspension. The int would be incremented by each suspender and suspension would be off if the value = 0.
(In the past I have successfully used such a pattern to control repetitive redraws)
1.) m_suspending is a property of CMyDoc because its behavior depends on it. Therefore it should be a member variable of CMyDoc.
2.) If Suspender can be created within multiple threads then m_suspending should be synchronized. And global variables are bad anyway.
3.) RAII is the keyword and your example looks similar to the way how mutex and lock_guard interact.
4.) You do not need a name for every trivial "pattern". RAII is fundamental in C++.
Related
In this thread, the following is said about singleton instances:
The static variable can be static to the GetInstance() function, or it can be static in the Singleton class. There's interesting tradeoffs there.
What are these trade-offs? I am aware that, if declared as a static function variable, the singleton won't be constructed until the function is first called. I've also read something about thread-safety, but am unaware of what exactly that entails, or how the two approaches differ in that regard.
Are there any other major differences between the two? Which approach is better?
In my concrete example, I have a factory class set up as a singleton, and I'm storing the instance as a static const field in the class. I don't have a getInstance() method, but rather expect the user to access the instance directly, like so: ItemFactory::factory. The default constructor is private, and the instance is allocated statically.
Addendum: how good of an idea is it to overload operator() to call the createItem() method for the singleton, such that Items can be created like so: ItemFactory::factory("id")?
What are these trade-offs?
This is the most important consideration:
The static data member is initialized during the static initialization at the start of the program. If any static object depends on the singleton, then there will be a static initialization order fiasco.
The function local static object is initialized when the function is first called. Since whoever depends on the singleton will call the function, the singleton will be appropriately initialized and is not susceptible to the fiasco. There is still a - very subtle - problem with the destruction. If a destructor of a static object depends on the singleton, but the constructor of that object does not, then you'll end up with undefined behaviour.
Also, being initialized on the first time the function is called, means that the function may be called after the static initialization is done and main has been called. And therefore, the program may have spawned multiple threads. There could be a race condition on the initialization of the static local, resulting in multiple instances being constructed. Luckily, since C++11, the standard guarantees that the initialization is thread safe and this tradeoff no longer exists in conforming compilers.
Thread safety is not an issue with the static data member.
Which approach is better?
That depends on what your requirements are and what version of the standard you support.
I vote for static function variable. The newer C++ standard require automatic thread safety for initialization of such variables. It's implemented in GNU C++ for about ten years already. Visual Studio 2015 also supports this. If you make a static pointer variable holding reference to your singleton object, you'll have to deal with thread issues manually.
In the other hand, if you make a static member pointer field like shown in in the snippet below, you will be able to change it from other static methods, maybe re-init this field with other instance upon handling request to change program configuration. However, the snippet below contains a bug just to remind you how difficult multithreading is.
class ItemFactory {
static std::atomic_flag initialized = ATOMIC_FLAG_INIT;
static std::unique_ptr<ItemFactory> theFactoryInstance;
public:
static ItemFactory& getInstance() {
if (!initialized.test_and_set(std::memory_order_acquire)) {
theFactoryInstance = std::make_unique<ItemFactory>();
}
return *theFactoryInstance;
}
};
I wouldn't advise you to implement your singleton as a global non-pointer variable initialized before entry to the main() function. Thread safety issues will go away along with implicit cache coherency overhead, but you're not able to control the initialization order of your global variables in any precise or portable way.
Anyway, this choice doesn't force any permanent design implications. Since this instance will reside in the private section of your class you may always change it.
I don't think overloading of operator() for a factory is a good idea. operator() have "execute" semantics while in factory it's gonna stand for "create".
What is the best approach to a singleton in c++?
Hide the fact that it's a singleton and give it value semantics.
How?
All singleton-ness ought to be an implementation detail. In this way, consumers of your class need not refactor their programs if you need to change the way you implement your singleton (or indeed if you decide that it should not really be a singleton after all).
Why ?
Because now your program never has to worry itself with references, pointers, lifetimes and whatnot. It just uses an instance of the object as if it were a value. Safe in the knowledge that the singleton will take care of whatever lifetime/resource requirements it has.
What about a singleton that releases resources when not in use?
no problem.
Here's an example of the two approaches hidden behind the facade of an object with value semantics.
imagine this use case:
auto j1 = jobbie();
auto j2 = jobbie();
auto j3 = jobbie();
j1.log("doh");
j2.log("ray");
j3.log("me");
{
shared_file f;
f.log("hello");
}
{
shared_file().log("goodbye");
}
shared_file().log("here's another");
shared_file f2;
{
shared_file().log("no need to reopen");
shared_file().log("or here");
shared_file().log("or even here");
}
f2.log("all done");
where a jobbie object is just a facade for a singleton, but the shared_file object wants to flush/close itself when not in use.
so the output should look like this:
doh
ray
me
opening file
logging to file: hello
closing file
opening file
logging to file: goodbye
closing file
opening file
logging to file: here's another
closing file
opening file
logging to file: no need to reopen
logging to file: or here
logging to file: or even here
logging to file: all done
closing file
We can achieve this using the idiom, which I'll call 'value-semantics-is-a-facade-for-singleton':
#include <iostream>
#include <vector>
// interface
struct jobbie
{
void log(const std::string& s);
private:
// if we decide to make jobbie less singleton-like in future
// then as far as the interface is concerned the only change is here
// and since these items are private, it won't matter to consumers of the class
struct impl;
static impl& get();
};
// implementation
struct jobbie::impl
{
void log(const std::string& s) {
std::cout << s << std::endl;
}
};
auto jobbie::get() -> impl& {
//
// NOTE
// now you can change the singleton storage strategy simply by changing this code
// alternative 1:
static impl _;
return _;
// for example, we could use a weak_ptr which we lock and store the shared_ptr in the outer
// jobbie class. This would give us a shared singleton which releases resources when not in use
}
// implement non-singleton interface
void jobbie::log(const std::string& s)
{
get().log(s);
}
struct shared_file
{
shared_file();
void log(const std::string& s);
private:
struct impl;
static std::shared_ptr<impl> get();
std::shared_ptr<impl> _impl;
};
// private implementation
struct shared_file::impl {
// in a multithreaded program
// we require a condition variable to ensure that the shared resource is closed
// when we try to re-open it (race condition)
struct statics {
std::mutex m;
std::condition_variable cv;
bool still_open = false;
std::weak_ptr<impl> cache;
};
static statics& get_statics() {
static statics _;
return _;
}
impl() {
std::cout << "opening file\n";
}
~impl() {
std::cout << "closing file\n";
// close file here
// and now that it's closed, we can signal the singleton state that it can be
// reopened
auto& stats = get_statics();
// we *must* use a lock otherwise the compiler may re-order memory access
// across the memory fence
auto lock = std::unique_lock<std::mutex>(stats.m);
stats.still_open = false;
lock.unlock();
stats.cv.notify_one();
}
void log(const std::string& s) {
std::cout << "logging to file: " << s << std::endl;
}
};
auto shared_file::get() -> std::shared_ptr<impl>
{
auto& statics = impl::get_statics();
auto lock = std::unique_lock<std::mutex>(statics.m);
std::shared_ptr<impl> candidate;
statics.cv.wait(lock, [&statics, &candidate] {
return bool(candidate = statics.cache.lock())
or not statics.still_open;
});
if (candidate)
return candidate;
statics.cache = candidate = std::make_shared<impl>();
statics.still_open = true;
return candidate;
}
// interface implementation
shared_file::shared_file() : _impl(get()) {}
void shared_file::log(const std::string& s) { _impl->log(s); }
// test our class
auto main() -> int
{
using namespace std;
auto j1 = jobbie();
auto j2 = jobbie();
auto j3 = jobbie();
j1.log("doh");
j2.log("ray");
j3.log("me");
{
shared_file f;
f.log("hello");
}
{
shared_file().log("goodbye");
}
shared_file().log("here's another");
shared_file f2;
{
shared_file().log("no need to reopen");
shared_file().log("or here");
shared_file().log("or even here");
}
f2.log("all done");
return 0;
}
I'm helping a student with their homework, which is a basic threading exercise. Unfortunately, though they're required to use C++11, they're forbidden from using std::thread. I don't see the rationale, but it's not my homework.
Here's the class:
class VaccineInfo {
public:
VaccineInfo(const std::string &t_input_filename):
input_filename(t_input_filename)
{ }
VaccineInfo() = delete;
static void *count_vaccines(void *t_vi);
int v1_count() { return vaccine_count["v1"]; }
int v2_count() { return vaccine_count["v2"]; }
int v3_count() { return vaccine_count["v3"]; }
private:
std::string input_filename;
std::map<std::string, int> vaccine_count {
{ "v1", 0 },
{ "v2", 0 },
{ "v3", 0 }
};
};
void *VaccineInfo::count_vaccines(void *t_vi) {
VaccineInfo *vi = reinterpret_cast<VaccineInfo*>(t_vi);
std::ifstream input_file;
std::string input_line;
input_file.open(vi->input_filename);
if (!input_file.good()) {
std::cerr << "No such file " << vi->input_filename << std::endl;
return nullptr;
}
while (std::getline(input_file, input_line)) {
vi->vaccine_count[input_line]++;
}
return nullptr;
}
And here's where pthreads comes in.
std::vector<std::string> filenames = find_filenames(".");
std::vector<pthread_t> thread_handles;
std::vector<VaccineInfo> vi_vector;
vi_vector.reserve(filenames.size());
for(const std::string &filename : filenames) {
pthread_t tid;
thread_handles.push_back(tid);
vi_vector.emplace_back(VaccineInfo(filename));
pthread_create(
&thread_handles.back(), nullptr, &VaccineInfo::count_vaccines,
static_cast<void*>(&vi_vector.back()));
}
for (const pthread_t tid : thread_handles) {
pthread_join(tid, nullptr);
}
It's a pretty basic exercise, except for how much fluff you have to do to get the old and the new to play nice. And that's what's got me wondering - does using a static member method as the start_routine argument to pthread_create have any undesirable side effects? I know static member variables and functions don't "belong" to any objects, but I normally think of static variables as being one-per-class, regardless of the number of objects. If there's only one copy of the static member function, as well, that seems like you'd be shooting yourself in the foot for parallelization.
Would it just be better, in this case, to make vaccine_count public and make count_vaccines() a global function?
Do hit me with whatever detail you can muster; I'm very curious. =) And, as always, thank you all for your time and effort.
except for how much fluff you have to do to get the old and the new to play nice.
Well, in the STL, that's essentially what the std::thread is actually doing. If you create a thread and force it to cause a stack unwinding, and if you look at said stack, you'll see a lot of weird pointer arithmetic happening with this and pthread_create (or CreateThread on Windows).
That being said, it's not unusual in any way to use a static function of a class that then calls a private member of that class on an object instance, even with the std::thread, it really just depends on what you need those functions to do.
does using a static member method as the start_routine argument to pthread_create have any undesirable side effects?
No. At least not from the perspective of functionality; that is, creating a thread on a static member won't cause any UB or crashes directly just because you are using a static function.
You do have to account for the fact that your operating on a static member function, but that's no different from having to account for constructors/destructors or any function of the language itself. Since this is a homework assignment, it's likely the professor is trying to teach "how things work" less than "how to use C++11".
Would it just be better, in this case, to make vaccine_count public and make count_vaccines() a global function?
Yes and no. Having vaccine_count as a private member then means that count_vaccines must be a friend or static function, and given that vaccine_count seems like an "important" data point that you wouldn't want a "user of the code" inadvertently setting, it's probably better to keep it private.
You could add getters and setters, but that might complicate the code unnecessarily.
You could also just make it a public variable if you trust the users of the code to protect that variable (unlikely), and you could also just make count_vaccines a free/global function, but then you need to have the function after the class declaration. And if the class is a complex class (maybe has templates or some other C++ notion), then it can really complicate the code in how you operate on the class.
So yes, it could go that way, but the professor is likely trying to teach the idea of what a static function is, how threads operate on the class and how pointers work within the constructs of this exercise, among other things.
If you have a static member variable, all objects access that variable.
That's not what static means in this context. The static keyword in C++ simply means that you do not need an object reference to call that code. So a static member variable can be accessed, not just by any object, but by any code, take this example:
class Data {
public:
static int x_val;
int y_val;
};
int Data::x_val; // have to declare it since it's static
int main(int argc, char* argv[]) {
Data::x_val = 10; // works because it's static.
Data::y_val = 10; // error: accessing a non-static member
Data obj;
obj.y_val = 10; // ok because it's a member variable
obj.x_val = 20; // this works as the complier ultimately translates this to `Data::x_val = 20`
// BUT, referencing a static member/function on an object instance is "bad form"
return 0;
}
If you have a static member function... can it be called on more than one core simultaneously?
The static keyword has no effect on which core, or thread, said function is called on or if can be done in parallel.
A CPU core can only execute 1 machine level instruction per clock cycle (so essentially, just 1 assembly instruction), when a C++ program is compiled, linked and assembled, it is these "assembled" set of instructions base on the syntax you wrote that are executed on the core (or cores) of your CPU, not the static functions.
That static function is just an address in memory that gets called on any number of threads on any CPU core that the OS determines at any given time in your program.
Yes, you could call an OS API that pins that thread of execution calling that function to a specific core, but that's a different subject.
And for a last little bit of fun for you, on an assembly level, C++ functions basically get compiled into C-like functions (an extreme over simplification, but merely for demonstration):
C++
class Data {
public:
void increment() {
this->y_val += 1024;
}
private:
int y_val;
};
int main() {
Data obj;
obj.y_val = 42;
obj.increment(); // obj.y_val == 1066
return 0;
}
C
struct Data {
int y_val;
};
void Data_increment(Data* this) {
this->y_val += 1024;
}
int main() {
Data obj;
obj.y_val = 42;
increment(&obj); // obj.y_val == 1066
return 0;
}
Again, an over simplification, but the point is to illustrate how it all builds to assembly and what the assembly does.
In this thread, the following is said about singleton instances:
The static variable can be static to the GetInstance() function, or it can be static in the Singleton class. There's interesting tradeoffs there.
What are these trade-offs? I am aware that, if declared as a static function variable, the singleton won't be constructed until the function is first called. I've also read something about thread-safety, but am unaware of what exactly that entails, or how the two approaches differ in that regard.
Are there any other major differences between the two? Which approach is better?
In my concrete example, I have a factory class set up as a singleton, and I'm storing the instance as a static const field in the class. I don't have a getInstance() method, but rather expect the user to access the instance directly, like so: ItemFactory::factory. The default constructor is private, and the instance is allocated statically.
Addendum: how good of an idea is it to overload operator() to call the createItem() method for the singleton, such that Items can be created like so: ItemFactory::factory("id")?
What are these trade-offs?
This is the most important consideration:
The static data member is initialized during the static initialization at the start of the program. If any static object depends on the singleton, then there will be a static initialization order fiasco.
The function local static object is initialized when the function is first called. Since whoever depends on the singleton will call the function, the singleton will be appropriately initialized and is not susceptible to the fiasco. There is still a - very subtle - problem with the destruction. If a destructor of a static object depends on the singleton, but the constructor of that object does not, then you'll end up with undefined behaviour.
Also, being initialized on the first time the function is called, means that the function may be called after the static initialization is done and main has been called. And therefore, the program may have spawned multiple threads. There could be a race condition on the initialization of the static local, resulting in multiple instances being constructed. Luckily, since C++11, the standard guarantees that the initialization is thread safe and this tradeoff no longer exists in conforming compilers.
Thread safety is not an issue with the static data member.
Which approach is better?
That depends on what your requirements are and what version of the standard you support.
I vote for static function variable. The newer C++ standard require automatic thread safety for initialization of such variables. It's implemented in GNU C++ for about ten years already. Visual Studio 2015 also supports this. If you make a static pointer variable holding reference to your singleton object, you'll have to deal with thread issues manually.
In the other hand, if you make a static member pointer field like shown in in the snippet below, you will be able to change it from other static methods, maybe re-init this field with other instance upon handling request to change program configuration. However, the snippet below contains a bug just to remind you how difficult multithreading is.
class ItemFactory {
static std::atomic_flag initialized = ATOMIC_FLAG_INIT;
static std::unique_ptr<ItemFactory> theFactoryInstance;
public:
static ItemFactory& getInstance() {
if (!initialized.test_and_set(std::memory_order_acquire)) {
theFactoryInstance = std::make_unique<ItemFactory>();
}
return *theFactoryInstance;
}
};
I wouldn't advise you to implement your singleton as a global non-pointer variable initialized before entry to the main() function. Thread safety issues will go away along with implicit cache coherency overhead, but you're not able to control the initialization order of your global variables in any precise or portable way.
Anyway, this choice doesn't force any permanent design implications. Since this instance will reside in the private section of your class you may always change it.
I don't think overloading of operator() for a factory is a good idea. operator() have "execute" semantics while in factory it's gonna stand for "create".
What is the best approach to a singleton in c++?
Hide the fact that it's a singleton and give it value semantics.
How?
All singleton-ness ought to be an implementation detail. In this way, consumers of your class need not refactor their programs if you need to change the way you implement your singleton (or indeed if you decide that it should not really be a singleton after all).
Why ?
Because now your program never has to worry itself with references, pointers, lifetimes and whatnot. It just uses an instance of the object as if it were a value. Safe in the knowledge that the singleton will take care of whatever lifetime/resource requirements it has.
What about a singleton that releases resources when not in use?
no problem.
Here's an example of the two approaches hidden behind the facade of an object with value semantics.
imagine this use case:
auto j1 = jobbie();
auto j2 = jobbie();
auto j3 = jobbie();
j1.log("doh");
j2.log("ray");
j3.log("me");
{
shared_file f;
f.log("hello");
}
{
shared_file().log("goodbye");
}
shared_file().log("here's another");
shared_file f2;
{
shared_file().log("no need to reopen");
shared_file().log("or here");
shared_file().log("or even here");
}
f2.log("all done");
where a jobbie object is just a facade for a singleton, but the shared_file object wants to flush/close itself when not in use.
so the output should look like this:
doh
ray
me
opening file
logging to file: hello
closing file
opening file
logging to file: goodbye
closing file
opening file
logging to file: here's another
closing file
opening file
logging to file: no need to reopen
logging to file: or here
logging to file: or even here
logging to file: all done
closing file
We can achieve this using the idiom, which I'll call 'value-semantics-is-a-facade-for-singleton':
#include <iostream>
#include <vector>
// interface
struct jobbie
{
void log(const std::string& s);
private:
// if we decide to make jobbie less singleton-like in future
// then as far as the interface is concerned the only change is here
// and since these items are private, it won't matter to consumers of the class
struct impl;
static impl& get();
};
// implementation
struct jobbie::impl
{
void log(const std::string& s) {
std::cout << s << std::endl;
}
};
auto jobbie::get() -> impl& {
//
// NOTE
// now you can change the singleton storage strategy simply by changing this code
// alternative 1:
static impl _;
return _;
// for example, we could use a weak_ptr which we lock and store the shared_ptr in the outer
// jobbie class. This would give us a shared singleton which releases resources when not in use
}
// implement non-singleton interface
void jobbie::log(const std::string& s)
{
get().log(s);
}
struct shared_file
{
shared_file();
void log(const std::string& s);
private:
struct impl;
static std::shared_ptr<impl> get();
std::shared_ptr<impl> _impl;
};
// private implementation
struct shared_file::impl {
// in a multithreaded program
// we require a condition variable to ensure that the shared resource is closed
// when we try to re-open it (race condition)
struct statics {
std::mutex m;
std::condition_variable cv;
bool still_open = false;
std::weak_ptr<impl> cache;
};
static statics& get_statics() {
static statics _;
return _;
}
impl() {
std::cout << "opening file\n";
}
~impl() {
std::cout << "closing file\n";
// close file here
// and now that it's closed, we can signal the singleton state that it can be
// reopened
auto& stats = get_statics();
// we *must* use a lock otherwise the compiler may re-order memory access
// across the memory fence
auto lock = std::unique_lock<std::mutex>(stats.m);
stats.still_open = false;
lock.unlock();
stats.cv.notify_one();
}
void log(const std::string& s) {
std::cout << "logging to file: " << s << std::endl;
}
};
auto shared_file::get() -> std::shared_ptr<impl>
{
auto& statics = impl::get_statics();
auto lock = std::unique_lock<std::mutex>(statics.m);
std::shared_ptr<impl> candidate;
statics.cv.wait(lock, [&statics, &candidate] {
return bool(candidate = statics.cache.lock())
or not statics.still_open;
});
if (candidate)
return candidate;
statics.cache = candidate = std::make_shared<impl>();
statics.still_open = true;
return candidate;
}
// interface implementation
shared_file::shared_file() : _impl(get()) {}
void shared_file::log(const std::string& s) { _impl->log(s); }
// test our class
auto main() -> int
{
using namespace std;
auto j1 = jobbie();
auto j2 = jobbie();
auto j3 = jobbie();
j1.log("doh");
j2.log("ray");
j3.log("me");
{
shared_file f;
f.log("hello");
}
{
shared_file().log("goodbye");
}
shared_file().log("here's another");
shared_file f2;
{
shared_file().log("no need to reopen");
shared_file().log("or here");
shared_file().log("or even here");
}
f2.log("all done");
return 0;
}
Suppose I have a free function called InitFoo. I'd like to protect this function from being called multiple times by accident. Without much thought I wrote the following:
void InitFoo()
{
{
static bool flag = false;
if(flag) return;
flag = true;
}
//Actual code goes here.
}
This looks like a big wart, though. InitFoo does not need to preserve any other state information. Can someone suggest a way to accomplish the same goal without the ugliness?
Macros don't count, of course.
You can do it with some different ugliness:
struct InitFoo
{
InitFoo()
{
// one-time code goes here
}
};
void Foo()
{
static InitFoo i;
}
You're still using static, but now you don't need to do your own flag checking - static already puts in a flag and a check for it, so it only constructs i once.
Well, a constructor is only automatically called once. If you create a single instance of this class:
class Foo
{
public:
Foo(void)
{
// do stuff
}
}
Then //do stuff will only execute once. The only way to execute it twice is to create another instance of the class.
You can prevent this by using a Singleton. In effect, //do stuff can only possibly be called once.
I'd like to protect this function from being called multiple times by accident
To me, this sounds like an issue that will only come up during debugging. If that is the case, I would simply do the following:
void InitFoo()
{
#ifndef NDEBUG
static bool onlyCalledOnce = TRUE;
assert(onlyCalledOnce);
onlyCalledOnce = FALSE;
#endif
...
}
The purpose of this particular wart is easily discerned just by looking at it, and it will cause a nice, big, flashy assertion failure if a programmer ever makes the mistake of calling InitFoo more than once. It will also completely dissapear in production code. (when NDEBUG is defined).
edit: A quick note on motivation:
Calling an init function more than once is probably a big error. If the end user of this function has mistakenly called it twice, quietly ignoring that mistake is probably not the way to go. If you do not go the assert() route, I would recommend at least dumping a message out to stdout or stderr.
That is exactly how I'd do it. You could use some function pointer shuffling if you want an alternative:
static void InitFoo_impl()
{
// Do stuff.
// Next time InitFoo is called, call abort() instead.
InitFoo = &abort;
}
void (*InitFoo)() = &InitFoo_impl;
Do you also need it to be multi-thread safe? Look into the Singleton pattern with double-check locking (which is surprising easy to get wrong).
If you don't want a whole class for this, another simple way is:
In a .cpp (don't declare InitBlah in the .h)
// don't call this -- called by blahInited initialization
static bool InitBlah()
{
// init stuff here
return true;
}
bool blahInited = InitBlah();
No one can call it outside of this .cpp, and it gets called. Sure, someone could call it in this .cpp -- depends on how much you care that it's impossible vs. inconvenient and documented.
If you care about order or doing it at a specific time, then Singleton is probably for you.
I do exactly that all the time with situations that need that one-time-only-but-not-worth-making-a-whole-class-for. Of course, it assumes you don't worry about thread-related issues. I usually prefix the variable name with "s_" to make it clear that it's a static variable.
Hmmm... if you don't object to using Boost, then have a look at boost::call_once:
namespace { boost::once_flag foo_init_flag = BOOST_ONCE_INIT; }
void InitFoo() {
// do stuff here
}
void FooCaller() {
boost::call_once(&foo_init_flag, InitFoo);
// InitFoo has been called exactly once!
}
void AnotherFooCaller() {
boost::call_once(&foo_init_flag, InitFoo);
// InitFoo has been called exactly once!
}
Not that I am very excited about it, but this is just another way: function object.
#import <iostream>
class CallOnce {
private:
bool called;
public:
CallOnce() {
called = false;
}
void operator()(void) {
if (called) {
std::cout << "too many times, pal" <<std::endl;
return;
}
std::cout << "I was called!" << std::endl;
called = true;
}
};
int main(void) {
CallOnce call;
call();
call();
}
For debugging, I would like to add some counter variables to my class. But it would be nice to do it without changing the header to cause much recompiling.
If Ive understood the keyword correctly, the following two snippets would be quite identical. Assuming of course that there is only one instance.
class FooA
{
public:
FooA() : count(0) {}
~FooA() {}
void update()
{
++count;
}
private:
int count;
};
vs.
class FooB
{
public:
FooB() {}
~FooB() {}
void update()
{
static int count = 0;
++count;
}
};
In FooA, count can be accessed anywhere within the class, and also bloats the header, as the variable should be removed when not needed anymore.
In FooB, the variable is only visible within the one function where it exists. Easy to remove later. The only drawback I can think of is the fact that FooB's count is shared among all instances of the class, but thats not a problem in my case.
Is this correct use of the keyword? I assume that once count is created in FooB, it stays created and is not re-initialized to zero every call to update.
Are there any other caveats or headsup I should be aware of?
Edit: After being notified that this would cause problems in multithreaded environments, I clarify that my codebase is singlethreaded.
Your assumptions about static function variables are correct. If you access this from multiple threads, it may not be correct. Consider using InterlockedIncrement().
What you really want, for your long term C++ toolbox is a threadsafe, general purpose debug counters class that allows you to drop it in anywhere and use it, and be accessible from anywhere else to print it. If your code is performance sensitive, you probably want it to automatically do nothing in non-debug builds.
The interface for such a class would probably look like:
class Counters {
public:
// Counters singleton request pattern.
// Counters::get()["my-counter"]++;
static Counters& get() {
if (!_counters) _counters = new Counters();
}
// Bad idea if you want to deal with multithreaded things.
// If you do, either provide an Increment(int inc_by); function instead of this,
// or return some sort of atomic counter instead of an int.
int& operator[](const string& key) {
if (__DEBUG__) {
return _counter_map.operator[](key);
} else {
return _bogus;
}
}
// you have to deal with exposing iteration support.
private:
Counters() {}
// Kill copy and operator=
void Counters(const Counters&);
Counters& operator=(const Counters&);
// Singleton member.
static Counters* _counters;
// Map to store the counters.
std::map<string, int> _counter_map;
// Bogus counter for opt builds.
int _bogus;
};
Once you have this, you can drop it in at will wherever you want in your .cpp file by calling:
void Foo::update() {
// Leave this in permanently, it will automatically get killed in OPT.
Counters::get()["update-counter"]++;
}
And in your main, if you have built in iteration support, you do:
int main(...) {
...
for (Counters::const_iterator i = Counters::get().begin(); i != Countes::get().end(); ++i) {
cout << i.first << ": " << i.second;
}
...
}
Creating the counters class is somewhat heavy weight, but if you are doing a bunch of cpp coding, you may find it useful to write once and then be able to just link it in as part of any lib.
The major problems with static variables occur when they are used together with multi-threading. If your app is single-threaded, what you are doing is quite correct.
What I usually do in this situation is to put count in a anonymous namespace in the source file for the class. This means that you can add/remove the variable at will, it can can used anywhere in the file, and there is no chance of a name conflict. It does have the drawback that it can only be used in functions in the source file, not inlined functions in the header file, but I think that is what you want.
In file FooC.cpp
namespace {
int count=0;
}
void FooC::update()
{
++count;
}