Mam pytanie dotyczące nazw statycznych globalnych. Jeżeli postawimy przed nimi (zmienną czy też funkcją) specyfikator (przed deklaracją):
static
to taka zmienna (lub funkcja) nie będzie znana w innych plikach składających się na 1 program. Ale przecież i bez tego nazwa globalna nie jest znana w innych plikach - przecież ma ona zakres ważności tylko w obrębie tego pliku, gdzie została zadeklarowana ! (Ci co mają Symfonię C++ z 2006 r. mogą to wyraźnie przeczytać na 72 str.). Więc po co w ogóle takie coś :?: Przykładowo, jeżeli będę chciał skompilować taki program: 1_plik.cpp :
#include
using namespace std;
void funkcja1();
int x;
int main()
{
int x = 4;
cout << x << "\n\n";
funkcja1();
cout << "\n\n\n\n\n\n";
system("pause");
}
2_plik.cpp :
#include
using namespace std;
void funkcja1()
{
cout << "funkcja 1 \n\n";
cout << x; // <--- błąd ! bo 'x' nie jest znane w TYM pliku
}[/code]
To kompilator wyświetli błąd… Więc na jedno wychodzi - po co w ogóle potrzebne jest to ‘static’ :?:
Jeśli nie użyjesz słowa kluczowego static to wszystko będzie działać, jeśli zadeklarujesz funkcję z tym słowem kluczowym nie uda się tego skompilować. g++ rzuca błąd:
smth.hpp:2: error: ‘void smth()’ used but never defined
Ponieważ będzie ona znana tylko w tym pliku smth.hpp , zgadza się :?: No ale taki plik nagłówkowy załącza się do plików *.cpp, więc dodanie tam static (w pliku *.h ), będzie równoznaczne z:
// void smth();
Co prawda jeżeli był by tam specyfikator static, to funkcja była by znana tylko w pliku nagłówkowym - ale znowu tam nie ma, żadnych instrukcji, więc nie będzie też wywołań funkcji, ponieważ w tych plikach są same deklaracje - nazw, funkcji itp.
//plik add.cpp
int NF=999;
static int SF=666;
int rf() { return SF; }
static int srf() { return SF; }
//plik main.cpp
#include
using namespace std;
int rf();
extern int NF;
int srf(); // nie znajdzie tej srf() z pliku add.cpp ale znajdzie z pliku ext.cpp
extern int SF; // nie znajdzie tej SF z pliku add.cpp ale znajdzie z pliku ext.cpp
int main()
{
cout<<"rf()="<
cout<<"NF="<
cout<<"srf()="<
cout<<"SF="<
cin.get();
return 0;
}
//plik ext.cpp
int SF=333;
int srf() { return SF; }
Wszystkie trzy pliki razem, się skompilują i zostanie wygenerowany plik wykonywalny, ale rf zwróci 666, zaś srf zwróci 333.
Jeżeli nie dołączysz plik ext.cpp do projektu, to w wierszach main.cpp oznaczonych “// tu błąd linkera”, będzie błąd linkera :lol:
Jeżeli dołączysz plik ext.cpp do projektu ale zabierzesz klauzule static z pliku add.cpp, to też będzie błąd linkera, ponieważ nie będzie wiedział który SF ma użyć w main() ten z add.cpp czy ten z ext.cpp