2013-03-26 11 views
13

Uczę się C++ i nigdy nie mogę powiedzieć, kiedy potrzebuję użyć ::. Wiem, że muszę użyć std:: przed cout i cin. Czy to oznacza, że ​​wewnątrz pliku iostream programiści, którzy go utworzyli, stworzyli przestrzeń nazw o nazwie std i umieścili funkcje w przestrzeni nazw o nazwie std? Kiedy utworzyłem nową klasę, która nie jest w tym samym pliku co main() z jakiegoś powodu, muszę dodać ::.Używanie :: w C++

Na przykład, jeśli utworzę class o nazwie A, dlaczego muszę umieścić A:: przed funkcją, którą wykonuję, mimo że nie umieściłem jej w nazwie? Na przykład void A::printStuff(){}. Jeśli utworzę funkcję w main, dlaczego nie muszę wstawiać main::printStuf{}?

Wiem, że moje pytanie jest prawdopodobnie mylące, ale czy ktoś mógłby mi pomóc?

+2

A fine pytanie, ale trochę zbyt szeroki (IMO). Nazywa się to operatorem rozdzielczości, a wyszukiwanym terminem dalszej nauki jest * zasięg *. Wszystkie te nazwy ('cout', funkcje składowe' A') są zdefiniowane w * zakresach * i musisz rozwiązać zasięg (to znaczy powiedzieć kompilatorowi, gdzie szukać) za pomocą '::'. – GManNickG

+0

Prefiksem dla '::' może być zarówno przestrzeń nazw, jak i klasa. Ponieważ 'main' nie jest ani (jest to funkcja),' main :: printStuff' byłoby niepoprawne. –

+0

:: daje także pojęcie własności, gdy definicja jest częścią klasy lub przestrzeni nazw, powinieneś użyć ::, aby uzyskać do niej dostęp ... nie do końca, ale to daje ci poczucie. –

Odpowiedz

16

Masz prawie rację co do cout i cin. Są to obiekty (nie funkcje) zdefiniowane w przestrzeni nazw std. Oto ich zgłoszeń zdefiniowane przez standard C++

nagłówka <iostream> streszczenie

#include <ios> 
#include <streambuf> 
#include <istream> 
#include <ostream> 

namespace std { 
    extern istream cin; 
    extern ostream cout; 
    extern ostream cerr; 
    extern ostream clog; 

    extern wistream wcin; 
    extern wostream wcout; 
    extern wostream wcerr; 
    extern wostream wclog; 
} 

:: jest znany jako zakres rozdzielczości operatora. Nazwy cout i cin są zdefiniowane w std, więc musimy zakwalifikować ich nazwy za pomocą std::.

Klasy zachowują się trochę jak obszary nazw, ponieważ nazwy zadeklarowane w klasie należą do klasy. Na przykład:

class foo 
{ 
    public: 
    foo(); 
    void bar(); 
}; 

Konstruktor nazwie foo jest członkiem klasy o nazwie foo. Mają tę samą nazwę, ponieważ jest to jej konstruktor. Funkcja bar jest również członkiem foo.

Ponieważ są członkami foo, odnosząc się do nich spoza klasy, musimy zakwalifikować ich nazwiska. W końcu należą do tej klasy.Więc jeśli masz zamiar zdefiniować konstruktora i bar poza klasą, trzeba to zrobić tak:

foo::foo() 
{ 
    // Implement the constructor 
} 

void foo::bar() 
{ 
    // Implement bar 
} 

To dlatego, że są one zdefiniowane poza klasy. Jeśli kwalifikacja foo:: nie została umieszczona na nazwach, definiowałbyś kilka nowych funkcji w zasięgu globalnym, a nie jako członków foo. Na przykład, jest to zupełnie inny bar:

void bar() 
{ 
    // Implement different bar 
} 

To może mieć taką samą nazwę jak funkcja w klasie foo bo to w innym zakresie. Ten bar ma zasięg globalny, podczas gdy drugi bar należał do klasy foo.

+0

Dzięki! Najlepsza odpowiedź! – foobar5512

6

Urządzenie :: nazywane jest operatorem rozdzielczości zakresu. Może być stosowany tak:

::identyfikator
nazwa-klasy::identyfikator
nazw::identyfikator

Można o tym przeczytać tutaj
http://msdn.microsoft.com/en-us/library/b451xz31(v=vs.80).aspx

+0

Nie ma nic złego w ich łączeniu: 'myNamespace :: myClass :: myMember' lub' :: std :: cout'. – chris

+2

+1 do odparcia niewyjaśnionego downvote –

7

Urządzenia :: służą do wykrywania zakresów dereferencyjnych.

const int x = 5; 

namespace foo { 
    const int x = 0; 
} 

int bar() { 
    int x = 1; 
    return x; 
} 

struct Meh { 
    static const int x = 2; 
} 

int main() { 
    std::cout << x; // => 5 
    { 
    int x = 4; 
    std::cout << x; // => 4 
    std::cout << ::x; // => 5, this one looks for x outside the current scope 
    } 
    std::cout << Meh::x; // => 2, use the definition of x inside the scope of Meh 
    std::cout << foo::x; // => 0, use the definition of x inside foo 
    std::cout << bar(); // => 1, use the definition of x inside bar (returned by bar) 
} 

niezwiązane: Cout CIN i nie działa, ale przykłady obiektów strumieniowych.

EDIT ustalona jako Keine Lust zasugerował

+0

Ta odpowiedź jest całkiem jasna. +1 – frankliuao

+1

Nie powinno być 'statyczne const int x = 2;' w 'meh'? –