Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?
Autor: Piotr Szawdyński
Kurs C++

Przestrzeń nazw std

[lekcja] Rozdział 7. Co to jest przestrzeń nazw i jak z niej korzystać.
W poprzednim rozdziale poznaliśmy nową technikę wyświetlania danych opartą o zapis std::cout. Nie pisaliśmy jednak nic na temat zapisu std:: przyjmując, że po prostu tak się pisze i koniec. Warto więc dowiedzieć się czegoś więcej na ten temat, jeśli wiąże się z tym jakaś historia i głębsza idea.

Historia powstania przestrzeni nazw

Dawno, dawno temu, gdy słońce świeciło jasno, niebo było niebieskie i trawa zielona, niejaki Dennis Ritchie zamiast cieszyć się życiem - pracował nad swoim językiem programowania. Był to wówczas język C. Język C w stosunkowo krótkim czasie stał się dominującym językiem programowania systemów operacyjnych jak i aplikacji. Jego szybki rozwój przyczynił się również do powstawania coraz to nowych funkcji ułatwiających pisanie w tym języku. Wraz z rozwojem języka zaczął się jednak pojawiać problem - każda funkcja musiała mieć bowiem swoją unikatową nazwę. Rozwiązanie tego problemu dostrzeżono w programowaniu obiektowym. Istotnym problemem był jednak fakt, że język C jest językiem strukturalnym w którym standard nie przewidywał takich możliwości. Na przełomie lat powstał więc język C++, który z definicji miał być kompatybilny ze swoim poprzednikiem oraz umożliwić jednocześnie programowanie obiektowe.

Pomimo, iż pojawiła się możliwość programowania obiektowego - programiści niechętni byli do 'przesiadania się' na nowy język. Wielu uważało wówczas, że programowanie obiektowe to sztuka dla sztuki i stratą czasu jest nauka nowego języka, skoro bardzo dobrze sprawdza się poczciwe C. Ideą języka C++ było jednak zachowanie kompatybilności z językiem C, a co za tym idzie powstało również hasło: "Najpiękniejsze w obiektowości C++ jest to, że nie trzeba wcale z niej korzystać".

Mając w zamyśle dość wymowne hasło zapaleńców języka C i widząc, że obiektowość nie rozwiązała problemu unikatowego nazywania funkcji, postanowiono poszukać innego rozwiązania. W języku C++ pojawiły się więc przestrzenie nazw. Chcąc być zgodnym ze standardem C - istniejących funkcji ze standardu C nie można było tknąć. Można było jednak podkreślić, które funkcje należą do standardu C++ więc wszystkie funkcje, klasy i szablony wprowadzone z tym językiem zapakowano do przestrzeni nazw std.

Konkluzja historii

Powyższa historia o ile jest bardziej lub mniej prawdziwa, o tyle nie ma ona istotnego znaczenia z naszego punktu widzenia. Ważniejsza jest w niej bowiem zawarta idea, a nie wydarzenia jakie miały miejsce w rzeczywistości. Chciałbym dla uściślenia jeszcze dodać, że historię wymyśliłem na potrzeby zobrazowania problemu. Być może faktycznie był taki przebieg wydarzeń jaki napisałem, jednak celem tego opracowania nie jest poznawanie historii lecz rozumienie znaczenia różnych zagadnień - w tym przypadku zagadnienia przestrzeni nazw.

Dostęp do przestrzeni nazw

Przypomnijmy najpierw przykład z poprzedniego rozdziału:
C/C++
#include <iostream>
int main()
{
    std::cout << "Czy ";
    std::cout << 3 + 4;
    std::cout << "jest wieksze od ";
    std::cout << "siedem";
    return 0;
}
Powyższy przykład jest zgodny z obecnie panującym standardem C++. W przeszłości ten sam kod wyglądał podobnie z tą różnicą, że nie występował przedrostek std::. Mając na uwadze wcześniej przedstawioną historię - poprawianie kodu napisanego we wczesnej młodości języka C++ byłoby zapewne dość uciążliwe i czasochłonne biorąc pod uwagę fakt, że wszystkie funkcje, klasy i szablony wprowadzone wraz z językiem C++ umieszczono w przestrzeni nazw std::. Rozwiązanie tego uciążliwego problemu wymaga jednak bardzo małego nakładu pracy o czym można przekonać się na poniższym przykładzie:
C/C++
#include <iostream>
using namespace std;

int main()
{
    cout << "Czy ";
    cout << 3 + 4;
    cout << "jest wieksze od ";
    cout << "siedem";
    return 0;
}
Dobiegając do końca rozdziału warto jeszcze wyciągnąć jakieś wnioski i wyjaśnić pokrótce znaczenie zapisu using namespace std;, którego zapewne i tak już się domyślasz.

Zapis using namespace ...;

Za pomocą słów kluczowych using namespace informujemy kompilator, że chcemy aby wszystkie funkcje, klasy i szablony należące do przestrzeni nazw nie wymagały przedrostka. Wyraz występujący po tych dwóch słowach kluczowych jest istniejącą nazwą przestrzeni. Dla standardowych bibliotek C++ jest to std.

Jaki zapis będziemy praktykowali

Pisząc kolejne rozdziały będę stale używał zapisu z przedrostkiem std::. Dzięki temu będziesz wiedział co należy do standardu C++, a co wywodzi się z języka C. Tworząc swoje programy możesz jednak pisać jak Ci będzie wygodniej - domyślam się, że im mniej pisania tym lepiej, ale ten wybór pozostawiam już Tobie.

Zadanie domowe

Ucząc się programowania warto również wspomnieć o błędach kompilacji na jakie można się natknąć podczas programowania. Sprawdźmy następujący kod:
C/C++
int main()
{
    cout << "Znajdz dwa rozne rozwiazania tego zadania." << endl;
    return 0;
}
Próba kompilacji powyższego programu nie powiedzie się. Zwróć uwagę na komunikaty jakie pojawiły się w logu kompilacji:
'cout' was not declared in this scope
'endl' was not declared in this scope
W ramach treningu doprowadź ten program do stanu w którym powyższy kod będzie się kompilował i działał. Zadanie to można rozwiązać na dwa różne sposoby - poznałeś je w tym rozdziale. Z programu nie wolno niczego usuwać.
Poprzedni dokument Następny dokument
Obsługa strumienia wyjściowego Pojęcie zmiennej i podstawowe typy danych