Frage Was ist ein statischer Block in c oder c ++?


Ich möchte wissen, was ist das statische Block in C oder C ++ mit einem Beispiel? Ich weiß, was ist statisch, aber was ist der Unterschied zwischen statischen und statischen Block?


9
2017-07-30 08:58


Ursprung


Antworten:


Eine andere Alternative ist, dass Sie nach der Analogie einer statischen Suche suchen Block in Java. Ein Codeblock, der beim Laden der Anwendung ausgeführt wird. Es gibt keine solche Sache in C ++, aber es kann gefälscht werden, indem man den Konstruktor von a benutzt statisches Objekt.

foo.cpp:

struct StaticBlock {
    StaticBlock(){
        cout << "hello" << endl;
    }
}


static StaticBlock staticBlock;

void main(int, char * args[]){

}

JEDOCH. Ich bin schon einmal davon gebissen worden, da es ein subtiler Randfall von C ++ ist Standard. Wenn das statische Objekt nicht mit einem von main aufgerufenen Code erreichbar ist, wird das Konstruktor des statischen Objekts kann oder darf nicht aufgerufen werden.

Ich habe festgestellt, dass mit gcc Hallo wird Ausgabe und mit Visual Studio wird es nicht.


28
2017-07-30 09:17



ich fand Dies antwort auf das Code-Projekt. Es beinhaltet eine zusätzliche statische Variable, aber ich glaube, es ist zuverlässiger als die Antwort von Bradgonesurfing. Im Grunde ist es das:

class Foo
{
public:
    static int __st_init;
private:
    static int static_init(){
        /* do whatever is needed at static init time */
        return 42;
    }
};
int Foo::__st_init = Foo::static_init();

Es bedeutet auch, dass Sie, wie die statischen Blöcke von Java, nicht unbedingt eine Instanz von haben müssen class FooDies ist nützlich, wenn die Klasse viele Daten aufnehmen kann und Sie einfach nur etwas automatisch aufrufen müssen, bevor sie geladen wird, und keine zusätzliche Instanz instanziieren. Sie können diesen genauen Codeblock testen. Ich habe es nur kompiliert (mit einer kleinen Ausgabe von static_init ()) und hatte main () print Foo :: __ st_init, nur um sicher zu gehen, und es hat gut geklappt.

$g++ -v

Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6.1/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.1-9ubuntu3' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++,go --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3)

BEARBEITEN:

Sorry, dass das so spät ist, aber ich habe was getestet Bradgonesurfen erwähnt:

Wenn Sie es testen, mein Zugriff auf die Variable in "nur um sicherzustellen,"   Sie stellen sicher, dass die Variable erreichbar ist und somit die Variable   initialisiert werden und damit static_init aufgerufen werden. Bist du dir sicher?   Wird ausgeführt, wenn Sie Foo :: __ st_init nicht drucken

Ich habe folgendes in main.cpp verwendet:

#include <iostream>

using namespace std;

class Foo
{
public:
    static int __st_init;
private:
    static int static_init(){
        /* do whatever is needed at static init time */
        cout << "Hello, World!";
        return 42;
    }
};
int Foo::__st_init = Foo::static_init();

int main(int argc, char** argv)
{
        return 0;
}

Ich habe mit zusammengestellt g++ ./main.cpp -o main und lief es und erhielt ein freundliches "Hallo, Welt!" Nachricht auf meiner Konsole. Um genau zu sein, habe ich auch die gleiche Version kompiliert aber ohne das Drucken und kompiliert g++ ./main.cpp -g -o main. Ich habe dann die ausführbare Datei mit gdb ausgeführt und hatte folgendes Ergebnis:

(gdb) break Foo::static_init
Breakpoint 1 at 0x400740: file ./main.cpp, line 12.
(gdb) start
Temporary breakpoint 2 at 0x4006d8: file ./main.cpp, line 19.
Starting program: /home/caleb/Development/test/main-c++ 

Breakpoint 1, Foo::static_init () at ./main.cpp:12
12              return 42;
(gdb) 

Hier ist eine aktuelle Ausgabe der Version für g ++: g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2


15
2018-05-14 01:51



In C / C ++ gibt es kein Konzept mit dem Namen "static block". Java hat es jedoch einen "statischen Block" ist ein Initialisierungscodeblock für eine Klasse, die genau einmal ausgeführt wird, bevor die erste Instanz einer Klasse erstellt wird. Das Grundkonzept "Zeug, das genau einmal läuft" kann in C / C ++ mit einer statischen Variablen simuliert werden, zum Beispiel:

int some_function(int a, int b)
{
 static bool once=true; 
 if (once)
 {
  // this code path runs only once in the program's lifetime 
  once=false; 
 } 
 ...
}

Dies ist jedoch nicht Thread-sicher. Es kann manchmal schwierig und schwierig sein, dies bei mehreren Threads richtig zu machen.


5
2017-07-30 09:15



Tatsächlich hat C ++ keine statischen Blöcke als Teil der Sprache, Sie kann Implementieren Sie statische Blöcke, ohne dass Sie (als Benutzer) Klassen oder Namespaces verwenden müssen und schreiben Sie:

#include "static_block.h" 

static_block {
     int x = 1;
     int y = 2;
     int z = x+y;
     std::cout << z << " = " << x " << " + " << y << "\n";
}

oder was auch immer du willst. Sie können diese nicht innerhalb von Klassen haben, nur im Dateiumfang. Siehe eine detaillierte Beschreibung von diesen in meinem Antworten auf eine verwandte Frage und den Code für static_block.h  Hier.

Hinweis: Dies erfordert nicht C ++ 11 und funktioniert gut mit alten Compilern.


1
2017-09-02 18:12



In C ++ gibt es das Konzept eines anonymen Namensraums.

foo.cpp:

namespace {
    int x;
    int y;
}

um den gleichen Effekt in C zu bekommen

foo.cpp:

static int x;
static int y;

In einfachen Worten exportiert der Compiler keine Symbole aus Übersetzungseinheiten, wenn sie entweder als statisch deklariert sind oder in einem anonymen Namespace.


0
2017-07-30 09:04