Was ist ein statischer Konstruktor?

Lesezeit: 7 Minuten

Was ist ein statischer Konstruktor
Vijay

Diese Frage wurde mir in einem Interview gestellt:

Was ist ein statischer Konstruktor?

Existiert es in C++? Wenn ja, erläutern Sie dies bitte anhand eines Beispiels.

  • Sieht so aus, als hätten Sie das C++-Interview verpasst und am Java/C#-Interview teilgenommen 😉

    – Alok Speichern

    27. April 11 um 12:23 Uhr


  • mögliches Duplikat von Was ist der Grund dafür, keinen statischen Konstruktor in C++ zu haben?

    – sbi

    27. April 11 um 13:01 Uhr

  • Wenn es an einen C++-Programmierer gerichtet ist, sollte es das tun erklären Fragen Sie nicht, was mit statischem Konstruktor gemeint ist, da es sich nicht um C++-Terminologie handelt. Beispielsweise könnte gefragt werden, ob der Konstruktor eine statische Verknüpfung haben könnte oder ob ihm das Schlüsselwort static vorangestellt werden könnte, um ein nicht spezifiziertes Verhalten zu erreichen ….

    – Toni Delroy

    28. April 11 um 7:05 Uhr

  • mögliches Duplikat von statischen Konstruktoren in C++? müssen private statische Objekte initialisieren

    – Mark Hurd

    17. Dezember 12 um 15:19 Uhr

  • mögliches Duplikat von Warum kann der Konstruktor in C++ nicht als statisch deklariert werden?

    – D Mehta

    11. Oktober 14 um 4:37 Uhr

Was ist ein statischer Konstruktor
Konrad Rudolf

C++ hat keine statischen Konstruktoren, aber Sie können sie emulieren, indem Sie eine statische Instanz einer verschachtelten Klasse verwenden.

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;

  • Ich vermute, dass class constructor sollte ein Freund des sein class has_static_constructor etwas Nützliches tun? Andernfalls ist es nur ein weiteres statisches Mitglied.

    – Davka

    27. April 11 um 13:33 Uhr

  • @davka gute Bemerkung. Tatsächlich ist das Verschachteln nicht besonders nützlich (abgesehen davon, den Bereich einzuschränken, was immer eine gute Sache ist).

    – Konrad Rudolf

    27. April 11 um 13:52 Uhr

  • @Nawaz Gemäß §7.1.5.3 ist es das. Aber GCC warf es mir zurück.

    – Konrad Rudolf

    16. Mai 11 um 15:07 Uhr

  • Du musst sein SEHR VORSICHTIG darüber, was Sie in einen solchen nicht lokalen statischen Objektkonstruktor einfügen. Wann dieser Konstruktor ausgeführt wird, ist nicht deterministisch und liegt sehr früh im Startvorgang. Eine ausführliche Erläuterung finden Sie in Scott Meyers Effective C++ (Punkt 47 in der 2. Auflage) zur NLSO-Initialisierung. Dies kann Sie in der Embedded-Welt wirklich beißen, wo das RTOS nicht verfügbar ist, wenn der Konstruktor läuft.

    – Tod

    25. April 2012 um 21:14 Uhr

  • @Tod Sehr gültiger Kommentar. Leider ist Lazy Loading etwas komplizierter. Im Wesentlichen würde ich es mit einer Statik lösen unique_ptr zu einer verschachtelten Klasse, die alle „statischen“ Mitglieder tatsächlich als nicht statische Mitglieder enthält und die mit 0 und initialisiert wird reset auf einen gültigen Zeiger, sobald darauf zugegriffen wird.

    – Konrad Rudolf

    25. April 12 um 22:06 Uhr


Was ist ein statischer Konstruktor
Nawaz

In C++ gibt es keinen statischen Konstruktor. In C# (und wahrscheinlich auch in Java) können Sie einen statischen Konstruktor definieren, der automatisch von der Laufzeit aufgerufen wird, um statische Member zu initialisieren.

Bei weiteren Fragen und Interesse können Sie dieses Thema lesen:

Was ist der Grund dafür, keinen statischen Konstruktor in C++ zu haben?

1643908808 807 Was ist ein statischer Konstruktor
Bärenvarietät

Da wir in C++ technisch gesehen keine statischen Konstruktoren haben, müssen Sie entscheiden, ob es sich lohnt, etwas Kniffliges zu tun, um das Problem zu erzwingen (z. B. eine statische Instanz einer verschachtelten Klasse zu verwenden), oder Ihren Code nur leicht umzustrukturieren, um a aufzurufen statischen Initialisierer früh im Leben Ihres Programms.

#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

Dieser Ansatz gefällt mir besser; Als Silberstreif am Horizont nimmt es das Nicht-aus der nicht-deterministischen Initialisierung heraus.

Es gibt jedoch einen Haken: Diese Technik ist unzureichend, wenn Sie versuchen, statische konstante Variablen zu initialisieren. Bei statischen konstanten Variablen müssen Sie sie für die Klasse privat machen und Getter bereitstellen, damit Außenstehende sie lesen können.

Hinweis: Ich habe diesen Code aktualisiert – er wird kompiliert und läuft erfolgreich ohne Warnungen über:

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

  • Dies ist bei weitem die BESTE Antwort auf die ewigen Fragen, wie/warum/ob/wann man einige Tricks anwenden sollte, um einen statischen Konstruktor in C++ zu emulieren.

    – jose.angel.jimenez

    3. September 14 um 7:29 Uhr

  • @bearvarine Zu deiner letzten Frage zu Meta-SO. Ja, das ist eine der Fragen, die es heutzutage bei SO nicht mehr gibt. Ich stimme jeden Tag über viele Fragen dieser Form ab, weil ich denke, dass ihr Wert für zukünftige Forscher gering ist (oder es bereits ein Duplikat gibt), und das OP es versäumt hat, die Site zu recherchieren, bevor es seine eigene Frage stellt. Gerade bei Fragen dieser Art hat sich der Moderationston geändert, da die Antworten mittlerweile schon allgegenwärtig sind.

    – πάντα ῥεῖ

    31. März 15 um 18:43 Uhr


  • Dies führt zu folgendem Fehler in VS2017: Severity Code Description Project File Line Suppression State LNK2001 unresolved external symbol “public: static class std::basic_string,class std::allocator > Foo::my_text_str” (?my_text_str@Foo@@2V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@A)

    – Harsh Kumar Narula

    29. Juli 17 um 12:26 Uhr


  • Ich bin gerade auf dieses Problem gestoßen. Und Ihre Lösung ist in realen Projekten, in denen Sie den Code nicht von Grund auf und ganz alleine geschrieben haben, nicht immer möglich.

    – Alex D

    28. September 18 um 22:32 Uhr

Statische Konstruktoren gibt es in C# und Java.
Sie werden verwendet, um statische Mitglieder einer Klasse zu initialisieren.
Die Laufzeit führt sie aus, bevor die Klasse zum ersten Mal verwendet wird.

In C++ gibt es so etwas nicht. Konstruktoren und Destruktoren, die normalerweise zum Erstellen oder Zerstören von Objektinstanzen verwendet werden. Es ist sinnlos, sie ohne entsprechende Objektinstanz aufzurufen. Sie können sie mit a emulieren Einzelling Muster.

1643908809 994 Was ist ein statischer Konstruktor
Job in

Ein statischer Konstruktor wird verwendet, um statische Daten einer Klasse zu initialisieren. C++ hat keinen statischen Konstruktor. Ein statischer Konstruktor kann jedoch emuliert werden, indem eine Friend-Klasse oder eine verschachtelte Klasse wie unten verwendet wird.

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

Ausgabe:

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

Vielleicht meinen sie das:

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

.

757990cookie-checkWas ist ein statischer Konstruktor?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy