Phillip Weber
Phillip Weber

Reputation: 21

Member function called only on initialization of first instance of a class (C++)

I have a member function for a base class that I only want to be called [once] on the initialization of the first instance of the class (whether it be a direct instance of the base class, or an inherited class). Basically, I want to avoid unnecessary function calls.

Upvotes: 2

Views: 2393

Answers (2)

Arne Mertz
Arne Mertz

Reputation: 24596

A thing that is done only done during the first time something happens is the initialization of function local statics during the first execution of the surrounding function. So how you could do it:

class X {
  static int firstInitFunc();

public:
  X() {
    static int onFirstCtorCall = firstInitFunc();
  }
};

Now the first time you create an X, onFirstCtorCall will be initialized (threadsafe), calling the function. Any following creation of X won't call that function again.

If you have multiple constructors on X, you'll still want only one call to the function. You can achieve that by either delegating to the constructor with the static variable or by using another static function:

C++11:

class X {
  static int firstInitFunc();

public:
  X() {
    static auto onFirstCtorCall = firstInitFunc();
  }
  X(int) : X() // delegate to X()
  { /* ... */ }
};

C++03:

class X {
  static int firstInitFunc();

  static void callFirstInit() {
    static int onFirstCtorCall = firstInitFunc();
  }

public:
  X() {
    callFirstInit();
  }
  X(int) {
    callFirstInit();
  }
};       

Update: I'll pick up juanchopanza's comment and provide an example using std::call_once:

C++11 using call_once

class X {
  static void firstInitFunc(); //see note to return types
  static std::once_flag firstInitFlag;

public:
  X() {
    std::call_once(firstInitFlag, firstInitFunc);
  }
  X(int) { 
    std::call_once(firstInitFlag, firstInitFunc);
  }
};

Note to return types: While in the case of function local statics' initialization used for the function call, that function must return a value, with wich the static will be initialized. In contrast, with std::call_once the function may not have a return type, because any returned value will not be evaluated.

Upvotes: 7

Spook
Spook

Reputation: 25927

Simple solution:

class C
{
private:
    static bool runOnce;

public:
    C()
    {
        if (!C::runOnce)
        { 
            C::runOnce = true;
            RunSth();
        }
    }
};

bool C::runOnce = false;

Upvotes: 2

Related Questions