IT박스

정적 생성자 란 무엇입니까?

itboxs 2020. 12. 8. 07:51
반응형

정적 생성자 란 무엇입니까?


이 질문은 인터뷰에서 나에게 요청되었습니다.

정적 생성자 란 무엇입니까?

C ++에 존재합니까? 그렇다면 예를 들어 설명해주십시오.


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;

C ++에는 정적 생성자가 없습니다. C # (그리고 아마도 Java에서도)에서 정적 멤버를 초기화하기 위해 런타임에 의해 자동으로 호출되는 정적 생성자를 정의 할 수 있습니다.

추가 질문과 관심이 있으시면 다음 주제를 읽으십시오.

C ++에서 정적 생성자가없는 이유는 무엇입니까?


기술적으로 C ++에 정적 생성자가 없기 때문에 문제를 강제하기 위해 (예 : 중첩 클래스의 정적 인스턴스 사용) 까다로운 작업을 수행 할 가치가 있는지 아니면 코드를 약간 재구성하여 a를 호출 할 가치가 있는지 결정해야합니다. 프로그램의 초기에 정적 이니셜 라이저.

#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

저는이 접근 방식이 더 좋습니다. 은색 라이닝으로, 비 결정적 초기화에서 비-아웃을 취합니다.

하지만 한 가지 문제가 있습니다. 정적 const 변수를 초기화하려는 경우이 기술은 충분하지 않습니다. 정적 const 변수의 경우 클래스 전용으로 설정하고 외부인이 읽을 수 있도록 getter를 제공해야합니다.

참고 :이 코드를 업데이트했습니다. 다음을 통해 경고없이 성공적으로 컴파일되고 실행됩니다.

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

정적 생성자는 C # 및 Java에 있습니다.
클래스의 정적 멤버를 초기화하는 데 사용됩니다.
런타임은 클래스가 처음 사용되기 전에이를 실행합니다.


C ++에는 그런 것이 없습니다. 일반적으로 개체의 인스턴스를 생성하거나 소멸하는 데 사용되는 생성자와 소멸자. 해당 객체 인스턴스없이 호출하는 것은 의미가 없습니다. 싱글 톤 패턴을 사용하여 에뮬레이션 할 수 있습니다 .


다음을 의미 할 수 있습니다.

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

정적 생성자는 클래스의 정적 데이터를 초기화하는 데 사용됩니다. 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();
}

산출:

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

C ++에는 정적 생성자와 같은 것이 없습니다.


비슷한 질문에 대한 내 대답참조하십시오 . C #의 정적 생성자 메타포는 C ++에서 수행 할 수 있습니다.


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:

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.      
*/

Other way to emulate static constructor behaviour is to use instance variable with private constructor and static factory method.

Cat* Cat::give_birth() {
  static Cat *myone = NULL;
  if (myone == NULL) {
    myone = new Cat();
  }
  return myone;
}

참고URL : https://stackoverflow.com/questions/5803953/what-is-a-static-constructor

반응형