Nagłówki i przestrzenie nazw

2008-03-30 16:11

Niestety, przestrzenie nazw w C++ nie mają takiego wdzięku jak pakiety w Javie czy assemblies w .NET. Zwłaszcza w połączeniu z plikami nagłówkowymi potrafią one sprawić nieco problemów. Jeśli bowiem nie będziemy uważali, to możemy dość łatwo zniwelować korzyści, jakie płyną z ich używania.

Ale po kolei. Jeśli mamy do czynienia z modułem kodu (plikiem .cpp), to możemy bez żadnych skrupułów umieszczać w nim deklaracje using lub using namespace. Jeśli tylko nie prowadzi to do niejednoznaczności, wszystko jest w porządku, bowiem zasięg tych deklaracji ogranicza się tylko i wyłącznie do tego jednego pliku.
Gorzej jest niestety z plikami nagłówkowymi. Ponieważ włączane są one tu i ówdzie przy pomocy dyrektywy #include, nie można tak po prostu wpisywać w nich deklaracji using namespace. Zostałyby one bowiem rozpropagowane do wszystkich plików, które dany nagłówek włączają, efektywnie niwelując wszelkie korzyści zamknięcia fragmentów kodu w przestrzeń nazw. Bo co to za namespace, który wszyscy “rozpakowują” i przenoszą jego zawartość do przestrzeni globalnej?…

Dlatego nie ma rady: w plikach nagłówkowych można używać wyłącznie nazw kwalifikowanych – poprzedzonych wszystkimi nazwami przestrzeni, jak np. XC::Base::GC::BlockInfo. W przeciwnym wypadku na pewno zaśmiecimy sobie którąś z przestrzeni (najczęściej globalną) identyfikatorami, które do niej nie należą – co będzie widoczne w systemach podpowiadania takich jak IntelliSense.

Tags: , ,
Author: Xion, posted under Programming »


4 comments for post “Nagłówki i przestrzenie nazw”.
  1. Paź:
    March 30th, 2008 o 18:21

    “w plikach nagłówkowych można używać wyłącznie nazw kwalifikowanych (…)”
    Niekoniecznie. Alternatywną opcją np. w funkcjach inline może być lokalna deklaracja otwarcia danej przestrzeni, np.

    1. inline void Fun()
    2. {
    3.     using namespace std;
    4.     //...
    5. }

    Jest to oczywiście kwestia gustu, ale takie wyjście pozwala często uniknąć operatora zasięgu, jednocześnie nie “zaśmiecając” globalnej przestrzeni nazw.

  2. Xion:
    March 30th, 2008 o 19:17

    Tak, ale to raczej wyjątek. W plikach nagłówkowych definiuje się głównie klasy, a w nich nie można zrobić:

    1. class Foo
    2. {
    3.     using namespace std;
    4. };

    (co swoją drogą jest dziwne).

  3. jarek:
    March 31st, 2008 o 8:02

    A co z deklaracjami typu
    using std::vector;
    Czy to tez niweluje cały ficzer namespace?

  4. Xion:
    March 31st, 2008 o 19:55

    Owszem, bo wtedy std::vector jest już dostępny poprzez nazwę niekwalifikowaną vector. Zaś

    1. using namespace std;

    to odpowiednik:

    1. foreach (Identifier iden in std)
    2.     using std::iden;

    W pierwszym przypadku zaśmiecasz nieumyślnie przestrzeń globalną jedną nazwą, a w drugim – wszystkimi nazwami z usingowanej przestrzeni.

Comments are disabled.
 


© 2019 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.