Join the Stack Overflow Community
Stack Overflow is a community of 6.6 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up
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....

share|improve this question
31  
Option #1 works correctly. Simply don't modify the member variable from other functions. If you can't trust other functions, you have already lost. – Dietrich Epp 22 hours ago
4  
Also note that member variables should not begin with underscore. _isInit is not a legal choice according to the language spec. – Dietrich Epp 22 hours ago
2  
@Jarod42 so by that reasoning, my usage of the _ is legal as long as MyOtherObj is in its own namespace.... – John 22 hours ago
2  
@John: You should inherit privately from MyOtherObj, as currently you can call isInit() from outside of the class. – Jarod42 22 hours ago
2  
@Owen that's a static “solution“, not working per object. – Felix Dombek 15 hours ago
up vote 19 down vote accepted

I don't see what is wrong with Option 1. If a class has so many responsibilities that another function may accidentally mess with the is_init member variable then the class should probably be made smaller.

However, if you want to encapsulate into another class that is less error prone, rather than using inheritance, I suggest you use composition:

class FirstTime {
    bool first_time = true;
public:
    bool operator()(){
          if (!first_time) 
              return false;
          first_time = false;
          return true;
    }
};

class MyObj {
    FirstTime first_time;
public:
    void myFunc(){
        if (first_time()){
            std::cout << "First time!\n";
        }
    } 
};

Live demo.

As with Option 1, you should think about what copy/move behavior do you want. e.g Should a copy of an initialized MyObj be considered initialized?

share|improve this answer
2  
I strongly disagree with using operator(). – Michael 20 hours ago
2  
@Michael Please explain why. – CHendrix 19 hours ago
5  
@Michael: indeed please explain why. It might be because you want everything to be as implicit as possible and therefore think that it should be done by operator bool() or operator void*() or something, so the user writes if (first_time). Or it might be because you want everything to be as explicit as possible and therefore think the user should write if (first_time.is_the_first_time()). Or something else. – Steve Jessop 18 hours ago
    
@CHendrix Because I believe the operation should be explicit. I see it as a misuse of operator overloads. if (first_time.is_the_first_time()) in Steve's example is pretty clunky but I would be in favour of something to that effect. – Michael 18 hours ago
    
@Michael I don't see why it is misuse. I am creating a functor that returns true the first time you call it. What is operator() for if it is not for creating functors? – Chris Drew 15 hours ago

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;
};
share|improve this answer
2  
Ah, the issue, mentioned in comments above, is that std::once_flag is not copyable/movable. – Chris Drew 18 hours ago
    
@Chris but one could copy the flag's state in a custom copy/move ctor, if the flag can be set manually. – Felix Dombek 15 hours ago
3  
@FelixDombek: The point is that the flag can't be written manually. But then, what does assignment even mean for an object requiring this behavior? – Ben Voigt 15 hours ago
    
@Ben you can't reset it, but you can set it via call_once so if the flag is already raised when the object is copied/moved, just call an empty lambda to raise the new flag too. Maybe not the most elegant way but should work if I'm not missing something here – Felix Dombek 14 hours ago
    
@Felix: one_time_init a, b; a.init(); a = b; How do you copy the "uninited" state from b onto a during the assignment? Should you even try? What does assignment even mean for this class? – Ben Voigt 14 hours ago

I see three reasonable options:

  1. Just use your option #1, a bool member variable.
  2. Create a little class for an init flag, that can be set, but not be unset.
  3. Use the public non-virtual interface (NVI) idiom, if you really want to be sure, that no-one messes with your flag.

A bool member variable

This would be my first choice. Make it private, of course. If your class has so many other data fields, that adding this new member appears painful, then this could be a sign of bad design of the entire class in the first place.

Often init() methods can be avoided completely by splitting up a class into two: A class A that contains the constructed data before the call to init() and a class B that is initialized upon construction. That way you can see if an object is initialized only by its type.

An init flag that can be set, but not reset

This class could look somewhat like this:

class InitFlag
{
public:
    void set()
    {
        isSet_ = true;
    }

    operator bool() const
    {
        return isSet_;
    }

private:
    bool isSet_ = false;
};

This way, member functions cannot mess up your flag as easily. As an author of a class, you should be able to trust your member functions enough, that they don't set this flag, unless they are called init().

The non-virtual interface idiom

You create a base class with an init() function that is public and non-virtual. This function checks, if init() has been called before, calls a private purely virtual doInit() function which is supposed to do the actual initialization and sets the init flag after that. It looks like this:

class InitializeBase
{
public:
    virtual ~InitializeBase() = default;

    bool isInit() const
    {
        return isInit_;
    }

    void init()
    {
        assert( !isInit() );
        doInit();
        isInit_ = true;
    }

private:
    virtual void doInit() = 0;

    bool isInit_ = false;
};

This has several security advantages:

  • Derived classes cannot modify isInit_.
  • Derived classes cannot call doInit(), as long as they don't make it public or protected (which would be very nasty). However, they can and must implement this function.
  • Hence doInit() function is statically guaranteed not to be called more than once, unless an assert() will trigger.
  • If you don't want the init() function to be public, then you can derive with the protected or the private attribute from InitializeBase.

The obvious drawback is that the design is more complicated and you get an additional virtual function call. For this reason the NVI idiom has become somewhat controversial.

share|improve this answer
1  
3. No need to use public inheritance, private would even be better. – Jarod42 22 hours ago
    
Can you give an example of 3 ? – John 22 hours ago
1  
Re your third example, the "security" is trivially bypassed. Derived classes are free to call their own overrides and can even change the access to public. Example – molbdnilo 21 hours ago
    
@molbdnilo Thanks. I fixed it. – Ralph Tandetzky 21 hours ago
    
wouldn't it be better to use a regular exception, since it is sufficient to leak a NDEBUG flag into compilation to have assert() disappear? – Patrick Trentin 21 hours ago

Here's a variant that wraps a function in a class.
Once the function is called, it's replaced with one that does nothing.

const std::function<void()> nop = [](){};

class Once
{
public:
    Once(std::function<void()> f) : m_function(f) {}
    void operator()()
    {
        m_function();
        m_function = nop;
    }    
private:
    std::function<void()> m_function;
};

class Foo
{
public:
    Foo(int x) 
        : m_function([this](){m_x += 1;}), 
          m_x(x) {}
    int get() const { return m_x; }
    void dostuff() { m_function(); }
private:
    int m_x;
    Once m_function;
};

int main()
{
    Foo f(0);
    cout << f.get() << endl; // 0
    f.dostuff();
    cout << f.get() << endl; // 1
    f.dostuff();
    cout << f.get() << endl; // 1
}
share|improve this answer
    
I like this implementation. I've changed a few things and submitted my own. – Michael 19 hours ago

molbdnilo's answer is pretty good and was along the same lines I was thinking. I've changed a few things which I personally think makes it more idiomatic.

#include <iostream>
#include <functional>

class Once
{
    bool isDone = false;    
public:
    void exec(std::function<void()> function)
    {
        if (!isDone)
        {
            function();
            isDone = true;
        }
    }
};

class MyObj {
    Once once = Once();

public:
    void myFunc()
    {
        once.exec( []{
            std::cout << "Hello, world!";
            // do some stuff
        });
    } 
};

int main()
{
    MyObj foo = MyObj();
    foo.myFunc();
    foo.myFunc();
    foo.myFunc();
}
share|improve this answer
    
This is basically a re-implementation of std::call_once. Also, using a lambda instead of std::binding to a private member function may be better (as it is now, what if someone calls myFuncImpl directly thus bypassing your check?) if there's concerns about that. If there are no such concerns, a boolean member variable is a cleaner solution anyway. – You 18 hours ago
    
As mentioned in the comments, once_flag is not moveable or copyable. Lamdba is a better solution, thanks. – Michael 17 hours ago

The solution at the top is very good, but this might be a better solution for an interesting special case.

I assume that the method shall only be executed once because it modifies the state of the class. For the special case that the method initializes some parts of the class, I think it is best to use an optional, either boost::optional or std::optional or std::experimental::optional, depending on what is available to you:

#include <boost/optional.hpp>

class X
{
    public:
        void init()
        {
            if( ! _x )
            {
                _x.reset( 5 );
            }
        }

    private:
        boost::optional<int> _x;
};
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.