2012-07-24 10 views
26

Mam nazw foo która zawiera liczbę całkowitą bar, ogłosił więc ...statyczne vs non-zmiennych statycznych w przestrzeni nazw

Foo.h:

namespace foo { 
    int bar; 
} 

Teraz gdybym to foo.h tylko w jednym plik, działa to dobrze. Ale pojawia się problem, gdy dołączę foo.h z dwóch lub więcej plików: Otrzymuję błąd linkera. Pomyślałem, że jeśli zadeklaruję bar jako static, mogę dołączyć foo.h w więcej niż jednym pliku. Wydaje mi się to dziwne, ponieważ nie wiedziałem, że można zadeklarować zmienną statyczną wewnątrz przestrzeni nazw. (co to właściwie znaczy?)

Dlaczego to działa? I co ważniejsze, dlaczego nie to działa bezstatic? Co oznacza static w przypadku używania w namespace?

+0

Awans. Był dokładnie mój problem i rozwiązany :) –

Odpowiedz

26

Istnieje wiele znaczeń dla static w różnych kontekstach. W tym konkretnym kontekście oznacza to, że zmienna ma wewnętrzne powiązanie, a zatem każda jednostka tłumaczeniowa, która zawiera ten nagłówek, będzie miała własną kopię zmiennej.

Należy zauważyć, że podczas gdy zostanie wyciszony błąd łącznika, spowoduje to zachowanie oddzielnej zmiennej foo::bar dla każdego wygenerowanego pliku obiektu (zmiany nie będą widoczne dla różnych plików obiektów).

Jeśli chcesz mieć jedną zmienną, powinieneś zadeklarować ją w nagłówku jako extern i podać jedną definicję w jednej jednostce tłumaczeniowej.

19

Po zadeklarowaniu zmiennej jako static oznacza to, że jej zakres jest ograniczony tylko do danej jednostki tłumaczeniowej. Bez static zasięg jest globalny.

Kiedy deklarujesz zmienną jako static wewnątrz pliku .h (wewnątrz lub bez namespace; nie ma znaczenia) i obejmują ten plik nagłówka w różnych plikach .cpp, zmienna static zostaje lokalnie zawężona do każdego z .cpp akta.
Teraz każdy plik .cpp zawierający ten nagłówek będzie miał własną kopię tej zmiennej.

Bez słowa kluczowego static kompilator wygeneruje tylko jedną kopię tej zmiennej, więc gdy tylko umieścisz plik nagłówkowy w wielu plikach .cpp, linker będzie narzekał na wiele definicji.

3

Problem wynika z posiadania więcej niż jednej definicji zmiennej. Definicje w różnych jednostkach tłumaczeniowych kolidują ze sobą, tak jak wiele nieliniowych definicji funkcji nie działałoby.

Gdy tworzysz zmienną statyczną, dajesz zmienną wewnętrzną łączność, więc każda jednostka tłumaczeniowa ma swoją własną niezależną kopię.

Najprawdopodobniej faktycznie chcesz umieścić tylko deklarację w nagłówku (przy użyciu extern), a następnie umieścić definicję w pliku implementacji.