什么是静态构造函数?

Vij*_*jay 62 c++

我在接受采访时问过这个问题:

什么是静态构造函数?

它存在于C++中吗?如果是,请举例说明.

Kon*_*lph 73

C++没有静态构造函数,但您可以使用嵌套类的静态实例来模拟它们.

class has_static_constructor {
    friend class constructor;

    struct constructor {
        constructor() { /* do some constructing here … */ }
    };

    static constructor cons;
};

// C++ needs to define static members externally.
has_static_constructor::constructor has_static_constructor::cons;
Run Code Online (Sandbox Code Playgroud)

  • 你必须*非常小心*关于你在这种非本地静态对象构造函数中放置的内容.当这个构造函数运行时是非确定性的,它将在启动过程中很早.关于NLSO初始化的Scott Meyer的Effective C++(第2版第47项)中可以找到详尽的解释.在构造函数运行时RTOS将无法使用的嵌入式环境中,这可能会让您感到非常恼火. (12认同)
  • @Tod非常有效的评论.不幸的是,延迟加载是相当复杂的.本质上我会用一个静态的`unique_ptr`解决它到一个嵌套类,它嵌套所有的"静态"成员,实际上是非静态成员,并且一旦它第一次被初始化为0并且"重置"为有效指针访问. (2认同)

Naw*_*waz 17

在C++中,没有静态构造函数.在C#中(也可能在Java中),您可以定义静态构造函数,该构造函数由运行时自动调用,以便初始化静态成员.

有关更多问题和兴趣,您可以阅读本主题:

在C++中没有静态构造函数的基本原理是什么?


bea*_*ine 9

因为我们在技术上没有C++中的静态构造函数,所以你必须决定是否值得做一些棘手的事情来强制解决问题(例如使用嵌套类的静态实例),或者只是稍微重构你的代码来调用静态初始化程序在程序生命的早期.

#include <iostream>           // cout, endl

class Foo {
   public:
      static int s_count;

      // Constructor definition
      Foo (int l, int w, int h)
      {
         cout <<"Foo ctor called." << endl;
         length = l;
         width  = w;
         height = h;

         // Increase every time object is created
         s_count++;
      }

      int vol ()
      {
         return length * width * height;
      }

      static void initCount()
      {
         s_count = 0;
      }

      static int getCount()
      {
         return s_count;
      }

   private:
      double length;     // Length of a box
      double width;      // Width  of a box
      double height;     // Height of a box
};

// Initialize static member of class Foo
int Foo::s_count;  // Initializing here is non-deterministic

int main(void) {

   Foo::initCount();  // Initializing here is deterministic

   // Print total number of objects before creating object.
   cout << "Inital Count: " << Foo::getCount() << endl;

   Foo Foo1(3, 1, 1);    // Declare box1
   Foo Foo2(8, 6, 2);    // Declare box2

   // Print total number of objects after creating object.
   cout << "Final Count: " << Foo::getCount() << endl;

   return 0;
}

Output:

$ static_init_test
Inital Count: 0
Foo ctor called.
Foo ctor called.
Final Count: 2
Run Code Online (Sandbox Code Playgroud)

我更喜欢这种方法; 作为一线希望,它取决于非确定性初始化.

但是有一个问题 - 如果你试图初始化静态const变量,这种技术是不够的.对于静态const变量,您必须将它们设置为类的私有,并为外部人员提供读取它们的getter.

注意:我更新了这段代码 - 它通过以下方式编译并成功运行,没有任何警告:

g++ static_init_test.cpp -std=c++11 -o static_init_test
Run Code Online (Sandbox Code Playgroud)


SLa*_*aks 6

静态构造函数存在于C#和Java中.
它们用于初始化类的静态成员.
运行时在首次使用类之前执行它们.