Jednak według komitetu ds. Standardów nienazwane przestrzenie nazw nie są wystarczającym zamiennikiem dla statycznej przestrzeni nazw . Nadal istnieje kilka przypadków, w których nienazwane przestrzenie nazw zawodzą i staticdziałają tylko .
legends2k
Odpowiedzi:
136
Zasadniczo odnosisz się do sekcji §7.3.1.1 / 2 ze standardu C ++ 03,
Używanie słowa kluczowego static jest przestarzałe podczas deklarowania obiektów w zakresie przestrzeni nazw; nienazwana przestrzeń nazw stanowi lepszą alternatywę.
Zauważ, że ten akapit został już usunięty w C ++ 11. staticfunkcje są według standardu nie są już przestarzałe!
Niemniej jednak przestrzenie nazw bez nazw są lepsze od słowa kluczowego static, głównie dlatego, że słowo kluczowe staticma zastosowanie tylko do deklaracji zmiennych i funkcji, a nie do typów zdefiniowanych przez użytkownika .
Poniższy kod obowiązuje w C ++
//legal codestaticintsample_function(){ /* function body */ }
staticint sample_variable;
Ale ten kod NIE jest ważny:
//illegal codestaticclasssample_class {/* class body */ };
staticstructsample_struct {/* struct body */ };
Rozwiązaniem jest więc nienazwana-przestrzeń nazw, czyli
//legal codenamespace
{
classsample_class {/* class body */ };
structsample_struct {/* struct body */ };
}
Mam nadzieję, że wyjaśnia, dlaczego unnamed-namespacejest lepszy od static.
Należy również zauważyć, że użycie słowa kluczowego static jest przestarzałe podczas deklarowania obiektów w zakresie przestrzeni nazw (zgodnie ze standardem).
Mówiąc bardziej ogólnie, nienazwana przestrzeń nazw umożliwia zewnętrzne połączenie. To właśnie umożliwia deklarację klasy jednostki lokalnej do translacji. Pozwala także np. Na użycie stałej łańcucha powiązania zewnętrznego jako argumentu szablonu.
Pozdrawiam i hth. - Alf
10
Jak zauważył Fred Nurk w innej odpowiedzi, wydaje się, że ta deprecateduwaga została usunięta z najnowszego C ++ 0x FCD (n3225).
Matthieu M.
37
Odpowiadasz na własne pytanie i dziękujesz sobie: -o
manpreet singh
12
Jaka byłaby różnica w porównaniu z samym zdefiniowaniem klasy w cpp (bez anonimowej przestrzeni nazw, bez statycznej)?
Luchian Grigore
6
@LuchianGrigore Problemy z łączeniem w przypadku 2 .cppto definiowanie klasy o tej samej nazwie.
Xaqq
9
Z tym wiąże się ciekawy problem:
Załóżmy, że używasz staticsłowa kluczowego lub nienazwanego, namespaceaby uczynić jakąś funkcję wewnętrzną w module (jednostka tłumaczenia), ponieważ ta funkcja jest przeznaczona do użytku wewnętrznego przez moduł i nie jest dostępna poza nim. (Nienazwane elementy namespacemają tę zaletę, że poza funkcjami definiują również dane i typy).
Z czasem plik źródłowy implementacji Twojego modułu się powiększa i chciałbyś podzielić go na kilka osobnych plików źródłowych, co pozwoliłoby na lepszą organizację kodu, szybsze znajdowanie definicji i samodzielną kompilację.
Ale teraz pojawia się problem: te funkcje nie mogą już dotyczyć staticmodułu, ponieważ statictak naprawdę nie odnoszą się do modułu , ale do pliku źródłowego (jednostki tłumaczeniowej). Jesteś zmuszony uczynić je niedozwolonymi, staticaby umożliwić dostęp do nich z innych części (plików obiektowych) tego modułu. Ale oznacza to również, że nie są już ukryte / prywatne dla modułu: mając zewnętrzne powiązania, można uzyskać do nich dostęp z innych modułów, co nie było Twoim pierwotnym zamiarem.
Bez nazwy też namespacenie rozwiązałoby tego problemu, ponieważ jest on również zdefiniowany dla konkretnego pliku źródłowego (jednostki tłumaczeniowej) i nie można uzyskać do niego dostępu z zewnątrz.
Byłoby wspaniale, gdyby można było określić, że pewne namespacejest private, że to, co określa się w nim, ma być używany wewnętrznie przez moduł do której należy. Ale oczywiście C ++ nie ma takiej koncepcji jak „moduły”, tylko „jednostki tłumaczeniowe”, które są ściśle powiązane z plikami źródłowymi.
Byłoby to i tak hack i ograniczone rozwiązanie, ale możesz dołączyć plik (i) cpp z wewnętrznymi funkcjami statycznymi lub z przestrzenią nazw do swoich „głównych” plików cpp. Następnie wyklucz te pliki cpp „satelity” z kompilacji i gotowe. Jedyny problem, jeśli masz dwa lub więcej `` głównych '' plików cpp i oba chcą użyć tej fajnej funkcji z jednego z `` satelitarnych '' plików cpp ...
Sergey
czy używanie dziedziczenia z funkcjami prywatnymi / chronionymi / publicznymi z funkcjami statycznymi nie jest rozwiązaniem?
Ali
C ++ 20 wprowadza moduły, które rozwiązują Twój problem.
static
działają tylko .Odpowiedzi:
Zasadniczo odnosisz się do sekcji §7.3.1.1 / 2 ze standardu C ++ 03,
Zauważ, że ten akapit został już usunięty w C ++ 11.
static
funkcje są według standardu nie są już przestarzałe!Niemniej jednak przestrzenie nazw bez nazw są lepsze od słowa kluczowego static, głównie dlatego, że słowo kluczowe
static
ma zastosowanie tylko do deklaracji zmiennych i funkcji, a nie do typów zdefiniowanych przez użytkownika .Poniższy kod obowiązuje w C ++
//legal code static int sample_function() { /* function body */ } static int sample_variable;
Ale ten kod NIE jest ważny:
//illegal code static class sample_class { /* class body */ }; static struct sample_struct { /* struct body */ };
Rozwiązaniem jest więc nienazwana-przestrzeń nazw, czyli
//legal code namespace { class sample_class { /* class body */ }; struct sample_struct { /* struct body */ }; }
Mam nadzieję, że wyjaśnia, dlaczego
unnamed-namespace
jest lepszy odstatic
.Należy również zauważyć, że użycie słowa kluczowego static jest przestarzałe podczas deklarowania obiektów w zakresie przestrzeni nazw (zgodnie ze standardem).źródło
deprecated
uwaga została usunięta z najnowszego C ++ 0x FCD (n3225)..cpp
to definiowanie klasy o tej samej nazwie.Z tym wiąże się ciekawy problem:
Załóżmy, że używasz
static
słowa kluczowego lub nienazwanego,namespace
aby uczynić jakąś funkcję wewnętrzną w module (jednostka tłumaczenia), ponieważ ta funkcja jest przeznaczona do użytku wewnętrznego przez moduł i nie jest dostępna poza nim. (Nienazwane elementynamespace
mają tę zaletę, że poza funkcjami definiują również dane i typy).Z czasem plik źródłowy implementacji Twojego modułu się powiększa i chciałbyś podzielić go na kilka osobnych plików źródłowych, co pozwoliłoby na lepszą organizację kodu, szybsze znajdowanie definicji i samodzielną kompilację.
Ale teraz pojawia się problem: te funkcje nie mogą już dotyczyć
static
modułu, ponieważstatic
tak naprawdę nie odnoszą się do modułu , ale do pliku źródłowego (jednostki tłumaczeniowej). Jesteś zmuszony uczynić je niedozwolonymi,static
aby umożliwić dostęp do nich z innych części (plików obiektowych) tego modułu. Ale oznacza to również, że nie są już ukryte / prywatne dla modułu: mając zewnętrzne powiązania, można uzyskać do nich dostęp z innych modułów, co nie było Twoim pierwotnym zamiarem.Bez nazwy też
namespace
nie rozwiązałoby tego problemu, ponieważ jest on również zdefiniowany dla konkretnego pliku źródłowego (jednostki tłumaczeniowej) i nie można uzyskać do niego dostępu z zewnątrz.Byłoby wspaniale, gdyby można było określić, że pewne
namespace
jestprivate
, że to, co określa się w nim, ma być używany wewnętrznie przez moduł do której należy. Ale oczywiście C ++ nie ma takiej koncepcji jak „moduły”, tylko „jednostki tłumaczeniowe”, które są ściśle powiązane z plikami źródłowymi.źródło