2012-06-07 19 views
14

Załóżmy mam ogłoszony funkcji (lub klasy, nie ma znaczenia) w pliku nagłówka, który jest częścią przestrzeni nazw foo:Najlepsze praktyki: używanie przestrzeni nazw lub ponowne otwieranie przestrzeni nazw?

namespace foo 
{ 
    void bar(); 
    … 
} 

Przez długi czas byłem znoszące nazw kiedy było określenie funkcji w pliku cpp:

namespace foo 
{ 
void bar() 
{ 
    doSomething(); 
    … 
} 
} 

to dlatego, że nauczyłem się to w ten sposób i to było używane w projekcie byłem w pracy. Tak naprawdę nigdy nie chociaż o tym dopiero niedawno, gdy natknąłem się na projekt, który korzystał z wykorzystaniem dyrektywę zamiast:

using namespace foo; 

void bar() 
{ 
    doSomething(); 
    … 
} 

Wreszcie istnieje możliwość korzystania z pełnej nazwy. Uważam to za dość nudne, zwłaszcza gdy zaangażowane są zajęcia z udziałem wielu członków. Moim zdaniem nie ma większego sensu, gdy cała zawartość pliku jest częścią jednego obszaru nazw.

void foo::bar() 
{ 
    doSomething(); 
    … 
} 

Moje pytanie brzmi, który z nich powinien być preferowany i dlaczego? Szczególnie w odniesieniu do dwóch pierwszych opcji (użycie dyrektywy vs. ponowne otwarcie przestrzeni nazw).

+3

Powiedziałbym, że to kwestia osobistych preferencji.Sam używam mieszanki zarówno pierwszej, jak i ostatniej alternatywy. –

+5

Zgadzam się, że jest to kwestia osobistych preferencji. 'foo :: bar' jest powtarzalne, ale możliwe do pomylenia, chociaż może to być nieistotne, jeśli ludzie szukają tylko Twojego źródła za pomocą IDE. –

+2

To tak, jakby pytać, czy lepiej używać kart lub 4 spacji. ** Nie marnuj małych rzeczy. ** :) – LihO

Odpowiedz

13

myślę najczystszym sposobem jest ponowne otwarcie przestrzeni nazw, a ja mam argumenty na jego poparcie:

  • z drugiego wariantu z dyrektywą using, nie jest jasne, że "Wdrożenie metody w tym obszarze nazw. Równie dobrze mógłbyś implementować darmową funkcję, która używa czegoś z przestrzeni nazw.
  • trzecia opcja jest zwykle używana do implementacji funkcji członków klasy. Jeśli patrzysz bezpośrednio w pliku cpp, nie jest jasne, czy implementujesz funkcję z przestrzeni nazw, chyba że wiesz, że przestrzeń nazw istnieje. Pierwszą rzeczą, która przychodzi do głowy jest to, że implementujesz funkcję członka klasy.
  • pierwsza jest najczystsza. Otworzysz przestrzeń nazw i zdefiniujesz w niej funkcję. Ta funkcja jest częścią przestrzeni nazw i jest to implementacja.
+0

Twój drugi punkt wypunktowania wydaje się mówić: "Nie robię X, dlatego pierwszą rzeczą, która przychodzi Ci do głowy, jest Y". Y niekoniecznie przychodzi pierwszemu do umysłów ludzi, którzy robią X, więc gdy będziesz przestrzegał konwencji, problem znika. Ponadto, jeśli nie możesz odróżnić nazw przestrzeni nazw od nazw klas, rozważ wybór lepszych nazw; -p. –

+0

@SteveJessop Nie sądzę, że to ważny punkt. 'X :: foo()' jest jedynym * sposobem definiowania metody klasy (chyba, że ​​jest inline). Natomiast w przestrzeniach nazw masz alternatywę. Dlaczego więc używać dwóch stylów do reprezentowania różnych rzeczy, kiedy można używać różnych stylów z wyraźnym zamiarem? –

+1

wydaje się, że istnieje tu podstawowy aksjomat, że bardzo ważne jest, aby różne rzeczy wyglądały tak różnie, jak to tylko możliwe. Myślę, że inne rzeczy mogą być ważniejsze, więc nie akceptuję tego aksjomatu (gdybym to zrobił, użyłbym C, ponieważ nie ma przeciążenia funkcji). –

6

Mimo że using namespace jest leniwym (a zatem i najbardziej kuszącym) rozwiązaniem, często nie jest to dobry pomysł. Poza tym, co Luchian mówi o tym, że deklaracje funkcji są niejednoznaczne (ktoś nowy w projekcie nie wiedziałby, czy jest to funkcja niezależna lub jedna w przestrzeni nazw), oraz fakt, że możesz później wprowadzić nazwę w przestrzeni nazw, zderzając się z jednym z nich. używając teraz, mam kolejny powód, dla którego sugerowałbym użycie trzeciej metody.

Stosując trzecią metodę, podajesz swój kod więcej konsystencja. Jeśli A znajduje się wewnątrz B, zawsze zdefiniowałbyś go jako A::B. Jeśli A jest klasą, a B jest funkcją w klasie, można napisać type A::B(args). Jeśli A jest klasą i B statycznym elementem, ponownie napiszesz type A::B = value. Teraz A jest przestrzenią nazw, ale wciąż jest to ta sama koncepcja: B jest zdefiniowany wewnątrz A, dlatego bardziej spójne jest ponowne użycie A::B.

(Istnieje dodatkowy bonus zdolności do przeszukiwania, jeśli twój edytor to np. ViM)