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