2014-05-11 9 views
15

Obecnie używam Naucz się C++ w 21-dniowej, drugiej edycji książki, aby dowiedzieć się o kodowaniu C++, wraz z Microsoft Visual C++ 2010 Express. Na końcu rozdziału 1 znajduje się małe ćwiczenie dotyczące pisania i kompilowania następującego kodu:Jaki jest związek między stacją nazw iostream a stacją nazw?

#include <iostream> 

int main() 
{ 
    cout << "Hello World!\n"; 
    return 0; 
} 

Całkiem proste, prawda? Jednak ku mojemu zdziwieniu kod nie będzie kompilować, z powodu tego błędu:

error C2065: 'cout' : undeclared identifier

zacząłem czyszczenie w internecie, a wkrótce znaleźć kilka rozwiązań here. Okazuje się, że musiałem dodać using namespace std; do mojego kodu!

Jednak w książce nie było żadnej wzmianki o przestrzeniach nazw, więc uznałem, że książka jest nieaktualna. (Wykorzystuje dyrektywę pre-procesora #include <iostream.h>!) Po kilku badaniach sieciowych znalazłem wiele informacji o przestrzeniach nazw, namespace std, wraz z historycznym tłem na <iostream.h> i <iostream>, a cały ten przepływ nowych informacji jest dla mnie dość mylący. (Nie wspominając o wszystkich niepotrzebnych Google Pozycje dotyczące chorób przenoszonych drogą płciową medycznych ...)

Więc oto kilka pytań, ja mam tak daleko:

  1. Jeśli jestem w tym bibliotekę iostream, dlaczego jest namespace musisz znaleźć cout? Czy jest gdzieś inny cout, który mógłby spowodować konflikt nazwy? Gdyby ktoś mógł to przedstawić, byłoby świetnie.

I jako bonus, niektóre tło historyczne:

  1. Co dokładnie było iostream.h zanim została zmieniona na iostream?

  2. Czy namespace odegrało rolę w tej zmianie?

+1

Nie trzeba dodawać do kodu "using namespace std;". Trzeba było powiedzieć 'std :: cout' lub' using std :: cout; 'wewnątrz' main'. – juanchopanza

+0

Ale dlaczego część 'std' jest nawet potrzebna? Czy w 'iostream' jest kilka' cout'? –

+0

Ponieważ 'cout' znajduje się w przestrzeni nazw' std'. – juanchopanza

Odpowiedz

14

Wszystkie standardowe definicje bibliotek znajdują się w standardowej przestrzeni nazw. Oznacza to, że nie są zdefiniowane w zakresie globalnym, tak, aby z nich korzystać trzeba zakwalifikować je w jeden z następujących sposobów:

  • std::cout
  • using namespace std
  • using std::cout

Dla instancja pozwala wziąć to:

// declarations 
int global_variable; 

namespace n { 
int variable2; 
} 

global_variable może mieć dostęp, jak to jest:

int x; 
x = global_variable; 

Ale variable2 nie jest częścią globalnej przestrzeni, ale część namespace n.

int x; 
x = variable2; // error variable2 identifier not found. 

Więc trzeba używać nazwy w pełni kwalifikowaną:

int x; 
x = n::variable2; 

W skrócie można napisać:

using namespace n; 
int x; 
x = variable2; // variable2 is searched in current namespace 
       // and in all namespaces brought in with using namespace 
       // Found ONLY in namespace n -> OK 

lub

using n::variable2; // this makes any unqualified reference to `variable2` 
        // to be resolved to `n::variable2` 
int x; 
x = variable2; 

jak dla nagłówka pliki, iostream.h został użyty b y wiele kompilatorów zanim istniał standard. Kiedy komitet próbował standaryzować, postanowili, że nagłówki C++ będą bez rozszerzenia, aby nie naruszyć kompatybilności z istniejącym kodem.

+0

Bardzo doceniane za wyjaśnienie! –

+0

Ładne wyjaśnienie, Pozdrawiam mate. –

1

W języku C++ można logicznie grupować identyfikatory na namespaces. cout Strumień jest wewnątrz std nazwy przestrzeni. Możesz go użyć na 3 sposoby.

  1. Napisz using namespace std u góry i użyj cout, tak jak Ty.
  2. Wpisz using std::cout u góry i użyj cout, tak jak Ty.
  3. Zastosowanie std::cout zamiast cout
3

1.If I am including the iostream library, why is a namespace needed to find cout ? Is there another cout somewhere that could cause a name clash?

To jest potrzebne, ponieważ standard C++ wymaga cout być wewnątrz przestrzeni nazw std. Nie mógłby być zderzeniu cout, ale nie w bibliotece standardowej (np swój własny kod, lub jakiś trzeci biblioteki strona.)

1.What exactly was iostream.h before it was changed to iostream ?

To może być cokolwiek, ponieważ nie jest częścią standardu, ale była to nazwa nagłówka przed standaryzacją, który stał się podstawą dla iostream. Zwykle deklarował on wszystkie nazwy w globalnej przestrzeni nazw, więc jest prawdopodobne, że przykład, na który patrzysz, został napisany przed standaryzacją.

2.Dod Czy grasz w tej zmianie?

To pytanie jest niejasne. Słowo kluczowe namespace może być używane wewnątrz implementacji i służy do deklarowania i definiowania danych, funkcji, typów itp. Wewnątrz przestrzeni nazw. Tak więc część z tej zmiany miała część .

namespace foo 
{ 
    void bar(); // declares foo::bar 
} 
4

Ponieważ linia ta rozpoczyna się #, to nazywa się „dyrektywa preprocesora”. Preprocesor czyta program przed skompilowaniem i wykonuje tylko te linie zaczynające się od #. Preprocesor ustawia kod źródłowy dla kompilatora.

Dyrektywa #include powoduje, że preprocesor włącza do programu zawartość innego pliku. Plik iostream zawiera kod, który pozwala programowi C++ wyświetlać dane wyjściowe na ekranie i pobierać dane z klawiatury. Pliki iostream są zawarte w programie w momencie pojawienia się dyrektywy #include.Plik iostream jest nazywany plikiem nagłówkowym i pojawia się u góry lub w nagłówku programu.

using namespace std;

C++ używa nazw organizować nazwy lub podmioty programu. Deklaruje, że program będzie oceniał podmioty należące do namespace zwane "std". Każda nazwa utworzona przez plik iostream jest częścią tego namespace.