仅在初始化类的第一个实例时调用的成员函数(C++)

Phi*_*ber 2 c++ inheritance member-functions

我有一个基类的成员函数,我只想在类的第一个实例的初始化(无论是基类的直接实例,还是继承类)上调用[once].基本上,我想避免不必要的函数调用.

Arn*_*rtz 7

只在第一次发生某事时才完成的事情是在第一次执行周围函数期间初始化函数局部静态.那你怎么做呢:

class X {
  static int firstInitFunc();

public:
  X() {
    static int onFirstCtorCall = firstInitFunc();
  }
};
Run Code Online (Sandbox Code Playgroud)

现在你第一次创建一个X,onFirstCtorCall将被初始化(threadsafe),调用该函数.任何后续创建X都不会再次调用该函数.

如果你有多个构造函数X,你仍然只需要调用一个函数.您可以通过使用静态变量委托构造函数或使用其他静态函数来实现:

C++ 11:

class X {
  static int firstInitFunc();

public:
  X() {
    static auto onFirstCtorCall = firstInitFunc();
  }
  X(int) : X() // delegate to X()
  { /* ... */ }
};
Run Code Online (Sandbox Code Playgroud)

C++ 03:

class X {
  static int firstInitFunc();

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

public:
  X() {
    callFirstInit();
  }
  X(int) {
    callFirstInit();
  }
};       
Run Code Online (Sandbox Code Playgroud)

更新:我会选择juanchopanza的评论并提供一个例子std::call_once:

C++ 11使用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);
  }
};
Run Code Online (Sandbox Code Playgroud)

注意返回类型:在函数调用初始化函数本地静态的情况下,该函数必须返回一个值,其中静态将被初始化.相反,std::call_once该函数可能没有返回类型,因为不会评估任何返回值.

  • 由[stmt.dcl]/4保证的+1线程安全性; 即使`std :: run_once`可能更惯用. (3认同)