C++ - basic function question
Is there any way to make a function call only once?
Suppose I have some class
struct A {
void MainRoutine(Params) {
// Want to call other routine only once
}
void OtherRoutine(Params) {
// Do something that should be done only once and
// what depends on the params
}
};
I want to call OtherRo开发者_开发问答utine
only once in MainRoutine
(I assume that MainRoutine
is going to be called N
times. I can't call OtherRoutine
from the constructor, because it accepts Params
which may not be available at the time when object is being constructed.
Basically I want to do something like
static bool called = false;
if (!called) {
OtherRoutine(Params);
called = true;
}
but I hope there is a more "beautiful" way of doing this... (which could be written in one line)
Maybe something using boost::function
or some part of boost
that I don't know about? :)
Thank you
Take a look at Boost Thread's one-time initialization mechanism
You can also put the call-only-once logic, which you already outlined, inside OtherRoutine
, causing it to return early if it has already been executed before.
Logically, its pretty much the same. Stylistically, it might be nicer.
You were definitely on the right track already. You should put your static 'called' variable inside your struct... ahem: you should make it a class instead, make it private, and make sure the state of the static variable is queried inside of OtherRoutine. You should not make it more complicated than it needs to be. Using boost, or anything else for so simple a mechanism is just overkill.
You could achieve this with boost::function and bind. Assuming you want OtherRoutine only to be called once per object,
struct A {
A() {
Routine = boost::bind(&A::OtherRoutine, this);
}
boost::function<void()> Routine;
private:
void MainRoutine() {
// Do stuff that should occur on every call
}
void OtherRoutine() {
Routine = boost::bind(&A::MainRoutine, this);
// Do stuff that should only occur once
MainRoutine();
}
};
A foo;
foo.Routine(); // OtherRoutine is called
foo.Routine(); // Now all subsequent calls will go to MainRoutine
foo.Routine();
I would suggest doing what the other people have said, though. While this may look 'cleaner,' it's overly complicated when compared to the alternatives.
Another way that verges on "cute" would be to have a static object and call your function from within its constructor. Something like...
struct OneShotOtherRoutine
{
OneShotOtherRoutine(A a, Params params)
{
a.OtherRoutine(params);
}
};
struct A
{
friend struct OneShotOtherRoutine;
public:
void MainRoutine(Params params)
{
static OneShotOtherRoutine(params);
// Main Routine code
}
private:
void OtherRoutine(Params params)
{
// Other routine code
}
};
You'd have to split things up so that each implementation could see the other struct's declaration, but this could do what you want, assuming it's acceptable that OtherRoutine
gets called when statics are initialized.
精彩评论