C++ 什么是静态构造函数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5803953/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 18:54:31  来源:igfitidea点击:

What is a static constructor?

c++

提问by Vijay

This question was asked to me in an interview:

在一次采访中被问到这个问题:

What is a static constructor?

什么是静态构造函数?

Does it exist in C++? If yes, please explain it with an example.

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

回答by Konrad Rudolph

C++ doesn't have static constructors but you can emulate them using a static instance of a nested class.

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;

回答by Nawaz

In C++, there is no static constructor. In C# (and probably in Java too), you can define static constructor which is called automatically by the runtime so as to initialize static members.

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

For further question and interest you can read this topic:

有关进一步的问题和兴趣,您可以阅读此主题:

What is the rationale for not having static constructor in C++?

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

回答by bearvarine

Since we do not technically have static constructors in C++, you have to decide whether it is worth it to do something tricky to force the issue (e.g. using a static instance of a nested class), or to just slightly restructure your code to call a static initializer early in your program's life.

由于我们在 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

I like this approach better; as a silver lining, it takes the non- out of non-deterministic initialization.

我更喜欢这种方法;作为一线希望,它消除了非确定性初始化。

There is one gotcha though -- this technique is insufficient if you are trying to initialize static const variables. For static const variables, you will have to make them private to the class and provide getters for outsiders to read them.

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

Note: I updated this code -- it compiles and runs successfully with no warnings via:

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

g++ static_init_test.cpp -std=c++11 -o static_init_test

回答by SLaks

Static constructors exist in C# and Java.
They are used to initialize static members of a class.
The runtime executes them before the class is first used.

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

回答by beduin

There is no such thing in C++. Constructors and destrcutors typically used to create or destruct instance of object. It's meaningless to call them without corresponding object instance. You can emulate them using a singletonpattern.

C++ 中没有这样的东西。构造函数和析构函数通常用于创建或销毁对象的实例。在没有对应的对象实例的情况下调用它们是没有意义的。您可以使用单例模式来模拟它们。

回答by beduin

May be they mean this:

可能他们的意思是:

class Cat
{
private:
Cat();
public:
static Cat getCat() {return Cat(); }
}

回答by Jobin

A static constructor is used to initialize static data of a class. C++ doesn't have static constructor. But a static constructor can be emulated by using a friend class or nested class as below.

静态构造函数用于初始化类的静态数据。C++ 没有静态构造函数。但是可以通过使用友元类或嵌套类来模拟静态构造函数,如下所示。

class ClassStatic{
private:
    static char *str;
public:
    char* get_str() { return str; }
    void set_str(char *s) { str = s; }
    // A nested class, which used as static constructor
    static class ClassInit{
    public:
        ClassInit(int size){ 
            // Static constructor definition
            str = new char[size];
            str = "How are you?";
        }
    } initializer;
};

// Static variable creation
char* ClassStatic::str; 
// Static constructor call
ClassStatic::ClassInit ClassStatic::initializer(20);

int main() {
    ClassStatic a;
    ClassStatic b;
    std::cout << "String in a: " << a.get_str() << std::endl;
    std::cout << "String in b: " << b.get_str() << std::endl;
    a.set_str("I am fine");
    std::cout << "String in a: " << a.get_str() << std::endl;
    std::cout << "String in b: " << b.get_str() << std::endl;
    std::cin.ignore();
}

Output:

输出:

String in a: How are you?
String in b: How are you?
String in a: I am fine
String in b: I am fine

回答by ulatekh

See my answerto a similar question. C#'s static-constructor metaphor can be done in C++.

请参阅对类似问题的回答。C# 的静态构造函数比喻可以在 C++ 中完成。

回答by Charis Engla

I think static constructor is used to initialize any static data, or to perform a particular action that needs to be performed once only. It is called automatically before the first instance is created or any static members are referenced. In++, we dont have anything called static constructor but you can mimic the functionality of the static constructor. Take a look at this C# static constructor:

我认为静态构造函数用于初始化任何静态数据,或执行只需要执行一次的特定操作。在创建第一个实例或引用任何静态成员之前自动调用它。在++中,我们没有任何称为静态构造函数的东西,但您可以模仿静态构造函数的功能。看看这个 C# 静态构造函数:

public class Bus  {
     // Static variable used by all Bus instances.
     // Represents the time the first bus of the day starts its route.
     protected static readonly DateTime globalStartTime;

     // Property for the number of each bus.
     protected int RouteNumber { get; set; }

     // Static constructor to initialize the static variable.
     // It is invoked before the first instance constructor is run.
     static Bus()
     {
         globalStartTime = DateTime.Now;

         // The following statement produces the first line of output, 
         // and the line occurs only once.
         Console.WriteLine("Static constructor sets global start time to {0}",
             globalStartTime.ToLongTimeString());
     }

     // Instance constructor.
     public Bus(int routeNum)
     {
         RouteNumber = routeNum;
         Console.WriteLine("Bus #{0} is created.", RouteNumber);
     }

     // Instance method.
     public void Drive()
     {
         TimeSpan elapsedTime = DateTime.Now - globalStartTime;

         // For demonstration purposes we treat milliseconds as minutes to simulate
         // actual bus times. Do not do this in your actual bus schedule program!
         Console.WriteLine("{0} is starting its route {1:N2} minutes after global start time {2}.",
                                 this.RouteNumber,
                                 elapsedTime.Milliseconds,
                                 globalStartTime.ToShortTimeString());
     }  }

 class TestBus  {
     static void Main()
     {
         // The creation of this instance activates the static constructor.
         Bus bus1 = new Bus(71);

         // Create a second bus.
         Bus bus2 = new Bus(72);

         // Send bus1 on its way.
         bus1.Drive();

         // Wait for bus2 to warm up.
         System.Threading.Thread.Sleep(25);

         // Send bus2 on its way.
         bus2.Drive();

         // Keep the console window open in debug mode.
         System.Console.WriteLine("Press any key to exit.");
         System.Console.ReadKey();
     }  }  /* Sample output:
     Static constructor sets global start time to 3:57:08 PM.
     Bus #71 is created.
     Bus #72 is created.
     71 is starting its route 6.00 minutes after global start time 3:57 PM.
     72 is starting its route 31.00 minutes after global start time 3:57 PM.      
*/

回答by Aaron Graham

In C++, if someone says "static constructor", they are generally referring to "static initialization" (and destruction). It's not uncommon to use this terminology.

在 C++ 中,如果有人说“静态构造函数”,他们通常指的是“静态初始化”(和销毁)。使用这个术语并不少见。