2

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

4

2 回答 2

7

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

class X {
  static int firstInitFunc();

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

现在您第一次创建X,onFirstCtorCall将被初始化(线程安全),调用该函数。任何后续创建X都不会再次调用该函数。

如果您有多个构造函数 on X,您仍然只需要一次调用该函数。您可以通过使用静态变量委托给构造函数或使用另一个静态函数来实现:

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();
  }
};       

更新:我会拿起 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);
  }
};

返回类型的注意事项:虽然在用于函数调用的函数局部静态初始化的情况下,该函数必须返回一个值,静态将被初始化。相反,withstd::call_once函数可能没有返回类型,因为任何返回值都不会被计算。

于 2013-06-12T06:23:26.907 回答
2

简单的解决方案:

class C
{
private:
    static bool runOnce;

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

bool C::runOnce = false;
于 2013-06-12T06:13:41.690 回答