Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to ensure that a method is executed only once for the lifetime of that object?

Tags:

class MyObj{ public:     void myFunc(){          //ToBeExecutedJustOnce     }  }; 

I have a function that I want to be executable only once for the lifetime of MyObj. There may be many instances of MyObj, and each should be able to execute that function once. So if I have:

MyObj first; MyObj second; MyObj third: first.myFunc(); // Should execute second.myFunc(); // Should execute third.myFunc(); // Should execute first.myFunc(); // Should not execute second.myFunc(); // Should not execute third.myFunc(); // Should not execute 

Options:

  1. member variable: If I use a member variable, then other functions within MyObj can access it and change it.
  2. global static variable: Can't work because first,second and third will all be checking the same variable.
  3. local static: Same problem as #2.

The only solution I have found, is to have MyObj inherit from another class

MyOtherObj{ private:     bool _isInit = false; public:     bool isInit(){           bool ret = true;           if (!_isInit){               ret = false;               _isInit = true;           }           return ret;     } };  class MyObj : public MyOtherObj { public:     void MyFunc(){         if (!isInit()){             //Do stuff...         }     }   }; 

Any better suggestion ?

EDIT: I don't care about thread safety!

EDIT: I do not want to execute the method in the constructor, simply because the method may need to be executed much later in the lifetime of the object....

like image 355
Rahul Iyer Avatar asked Jan 27 '17 09:01

Rahul Iyer


People also ask

What would you use to execute code only once when?

Code within lambda function is executed only once, when the static variable is initialized to the return value of lambda function.

What would you use to execute code only once when a class is first?

Unlike C++, Java supports a special block, called a static block (also called static clause) that can be used for static initialization of a class. This code inside the static block is executed only once: the first time the class is loaded into memory.


1 Answers

Use std::once_flag. It is not resettable from other methods (then again, if you cannot trust other methods of the same class, your development process is highly questionable), easy to use, and it is even thread-safe if you ever do care about that. It can be a bit less efficient in a single-threaded program.

#include <mutex>  class MyObj { public:     void MyFunc() {         std::call_once(initFlag, [=] {                 //Do stuff...             });     }  private:     std::once_flag initFlag; }; 
like image 78
Arne Vogel Avatar answered Oct 16 '22 08:10

Arne Vogel