앞에 붙은 이중 콜론“::”의 의미는 무엇입니까?


410

수정해야 할 클래스에서이 코드 줄을 찾았습니다.

::Configuration * tmpCo = m_configurationDB;//pointer to current db

그리고 이중 콜론이 클래스 이름 앞에 붙는 것이 정확히 무엇을 의미하는지 모르겠습니다. 그것 없이는 읽을 것입니다 : tmpCo클래스의 객체에 대한 포인터 선언은 Configuration...하지만 이중 이중 콜론은 나를 혼란스럽게합니다.

나는 또한 발견했다 :

typedef ::config::set ConfigSet;

7
답변이라고 생각하지 마십시오. en.wikipedia.org/wiki/Scope_resolution_operator에 대해 언급하겠습니다 . 이와 관련하여, 나체 ::란 글로벌 / 익명 네임 스페이스에서 변수를 참조합니다.
wkl

답변:


490

이렇게하면 현재있는 네임 스페이스에서 시작하는 대신 전역 네임 스페이스에서 확인이 수행됩니다. 예를 들어, 두 개의 다른 클래스가있는 경우 Configuration:

class Configuration; // class 1, in global namespace
namespace MyApp
{
    class Configuration; // class 2, different from class 1
    function blah()
    {
        // resolves to MyApp::Configuration, class 2
        Configuration::doStuff(...) 
        // resolves to top-level Configuration, class 1
        ::Configuration::doStuff(...)
    }
}

기본적으로이 경우 네임 스페이스가 다른 네임 스페이스 내부의 새로운 정의에 의해 혼란스러워 질 수 있으므로 전역 네임 스페이스까지 탐색 할 수 있습니다 MyApp.


이중 콜론 2 세트를 배치 한 이유는 무엇입니까? ::Configuration::doStuff(...)
Azurespot

@NoniA. 두 번째 이중 콜론 세트의 기능을 묻고 있습니까?
FCO

1
@WyattAnderson, 첫 번째 세트가 없습니다. 나는 ::두 용어 사이가 네임 스페이스 또는 클래스와 그 멤버를 의미 한다고 생각 합니다. 그러나 첫 번째는 어떻습니까?
Azurespot 2016 년

6
OP가 요구하는 것은 @Azurespot입니다. 이것이 바로이 게시물이 답변하는 질문입니다. 전역 네임 스페이스의 식별자를 사용해야합니다. 예를 다시보십시오
hungryWolf

193

::운영자는 범위 해상도 사업자라고하고 범위를 해결 그냥 것을 수행한다. 따라서 type-name 앞에 접두사를 지정하면 컴파일러에서 형식의 전역 네임 스페이스를 찾도록 지시합니다.

예:

int count = 0;

int main(void) {
  int count = 0;
  ::count = 1;  // set global count to 1
  count = 2;    // set local count to 2
  return 0;
}

122

이미 합리적인 답변이 많이 있습니다. 일부 독자에게 도움이 될 수있는 유추를 살펴 보겠습니다. 실행하려는 프로그램의 경로를 검색 할 때 ::파일 시스템 디렉토리 구분 기호 ' /' 와 매우 유사합니다 . 치다:

/path/to/executable

이것은 매우 명시 적입니다. 파일 시스템 트리의 정확한 위치에있는 실행 파일 만 PATH에 관계없이이 사양과 일치 할 수 있습니다. 비슷하게...

::std::cout

... C ++ 네임 스페이스 "tree"에서 똑같이 명시 적입니다.

같은 절대 경로와 대조, 당신은 (예를 들어 좋은 UNIX 쉘을 구성 할 수 있습니다 zsh을 해결하기 위해) 기준으로 현재 디렉토리 또는 어떤 요소 아래 경로를 PATH그렇다면, 환경 변수 PATH=/usr/bin:/usr/local/bin, 당신은 "에"있었다 /tmp다음, ...

X11/xterm

... /tmp/X11/xterm찾으면 행복하게 달릴 /usr/bin/X11/xterm/usr/local/bin/X11/xterm입니다. 마찬가지로이라는 네임 스페이스에 X있고 " using namespace Y"가 적용된다고 가정하면 ...

std::cout

... 어떤에서 볼 수 있습니다 ::X::std::cout, ::std::cout, ::Y::std::cout로 인해, 그리고 아마도 다른 장소 인수 종속적 조회 (ADL, 일명 코닉 조회). 따라서 ::std::cout정확히 어떤 객체를 의미하는지 분명하게 알 수 있지만 운 좋게도 올바른 마음으로 아무도 " std" 라는 자체 클래스 / 구조 또는 네임 스페이스를 만들거나 " " 라는 것을 만들지 cout않기 때문에 실제로 사용하는 std::cout것이 좋습니다.

주목할만한 차이점 :

1) 셸은의 순서를 사용하여 첫 번째 일치를 사용하는 PATH반면 C ++은 모호한 경우 컴파일러 오류를 발생시킵니다.

2) C ++에서는 선행 네임 스페이스가없는 이름을 현재 네임 스페이스에서 일치시킬 수 있지만 대부분의 UNIX 셸 .PATH.

3) C ++은 항상 전역 네임 스페이스를 검색합니다 ( /암시 적으로 your를 갖는 것처럼 PATH).

네임 스페이스 및 기호의 명시성에 대한 일반적인 토론

절대 ::abc::def::..."경로"를 사용하는 것은 때로는 사용중인 다른 네임 스페이스와 분리하는 데 유용 할 수 있지만, 라이브러리의 클라이언트 코드에서도 사용하는 컨텐츠 또는 다른 라이브러리의 일부를 제어 할 수는 없습니다. 반면, 기존 심볼의 "절대"위치에보다 밀접하게 연결되며, 네임 스페이스에서 암시 적 매칭의 이점을 줄입니다. 커플 링 감소, 네임 스페이스 간 코드 이동 용이성,보다 간결하고 읽기 쉬운 소스 코드 .

많은 것들과 마찬가지로 밸런싱 행위입니다. 아래 식별자의 C ++ 표준 풋 많이 std::그 이하 "독특한"있는 cout프로그래머가 코드에서 완전히 다른 무언가를 사용할 수있는 (예를 들어 merge, includes, fill, generate, exchange, queue, toupper, max). 두 개의 관련되지 않은 비표준 라이브러리는 작성자가 일반적으로 서로를 인식하지 못하거나 동일한 식별자를 사용할 가능성이 훨씬 높습니다. 그리고 C ++ 표준 라이브러리를 포함한 라이브러리는 시간이 지남에 따라 심볼을 변경합니다. 이 모든 것은 오래된 코드를 다시 컴파일 할 때, 특히 using namespaces를 많이 사용한 경우 모호성을 만듭니다 .이 공간에서 할 수있는 최악의 일은 허용입니다.using namespace임의로 많은 양의 직접 및 간접 클라이언트 코드가 사용할 네임 스페이스 및 모호성을 관리하는 방법에 대한 자체 결정을 내릴 수 없도록 헤더의 범위를 벗어나기 위해 헤더에 있습니다.

따라서 선행 ::은 C ++ 프로그래머 도구 상자에 알려진 충돌을 적극적으로 명확하게하거나 미래의 모호함을 제거 할 수있는 도구 중 하나입니다.


8
좋은 비유를 위해 +1. 유추는 교육 도구로 거의 IMO를 사용하지 않습니다.
Trevor Boyd Smith

38

::범위 확인 연산자입니다. 무언가의 범위를 지정하는 데 사용됩니다.

예를 들어 ::다른 모든 네임 스페이스 외부의 전역 범위 만 있습니다.

some::thing 다음 방법 중 하나로 해석 될 수 있습니다.

  • someA는 공간 (글로벌 범위, 또는 현재 하나 이상의 외측 범위) 및 thingA는 입력 하는 기능 , 객체 또는 중첩 된 공간 ;
  • some현재 범위에서 사용할 수 있는 클래스 이며 클래스thing멤버 객체 , 함수 또는 유형 입니다 some.
  • 클래스의 멤버 함수 , some될 수 기본형 전류 형 (또는 전류 타입 자체) 및 thing그 다음,이 클래스의 하나의 부재, 인 형태 , 기능 또는 목적 .

에서처럼 중첩 범위를 가질 수도 있습니다 some::thing::bad. 여기서 각 이름은 유형, 객체 또는 네임 스페이스 일 수 있습니다. 또한 마지막 bad것은 함수일 수 있습니다. 함수는 내부 범위 내에서 아무것도 노출시킬 수 없으므로 다른 함수는 할 수 없습니다.

따라서 예제로 돌아 가면 ::thing전역 범위에서 유형, 함수, 객체 또는 네임 스페이스 만 될 수 있습니다.

사용하는 방식은 (포인터 선언에서 사용되는) 전역 범위의 유형임을 제안합니다.

이 답변이 스코프 해상도를 이해하는 데 도움이되도록 완전하고 정확하기를 바랍니다.


2
@obounaim이 코드를 고려하십시오 liveworkspace.org/code/3Wabw0$5 class some { protected: int thing; }; class some_ext : public some { float thing; void action(){ some::thing = 42; thing = 666; } }; 여기 some에 기본 클래스가 some_ext있으며 some::thingsome_ext의 멤버 함수에 쓸 때 thing기본 유형에 객체를 의미합니다 some. 없이 some::, thing혼자 수단 thing가장 가까운 범위, 즉 some_ext::thing. 더 명확합니까?
Klaim

17

:: 네임 스페이스 나 클래스에 무언가 (변수, 함수, 클래스, typedef 등)를 연결하는 데 사용됩니다.

앞에 왼쪽이 없으면 ::전역 네임 스페이스를 사용하고 있다는 사실을 강조합니다.

예 :

::doMyGlobalFunction();


10

해당 범위 확인 연산자, 숨겨진 전역 이름은 범위 확인 연산자 ::
를 사용하여 참조 할 수 있습니다 .

int x;
void f2()
{
   int x = 1; // hide global x
   ::x = 2; // assign to global x
   x = 2; // assign to local x
   // ...
}

10

(이 답변은 OP가 이미 문제를 해결했기 때문에 대부분 Google 직원을위한 것입니다.) prepended의 의미 :: 범위-resulution 연산자- 다른 답변에 설명되어 있지만 사람들이 왜 그것을 사용하고 있는지 추가하고 싶습니다.

"다른 이름이 아닌 전역 네임 스페이스에서 이름을 가져옵니다"라는 의미입니다. 그러나 왜 이것이 명시 적으로 철자가 필요한가?

사용 사례-네임 스페이스 충돌

글로벌 네임 스페이스와 로컬 / 중첩 네임 스페이스에서 동일한 이름을 사용하면 로컬 네임 스페이스가 사용됩니다. 따라서 전 세계를 원한다면 앞에 추가하십시오 ::. 이 사례는 @Wyatt Anderson의 답변에 설명되어 있습니다.

유스 케이스-비 멤버 기능 강조

멤버 함수 (메서드)를 작성할 때 다른 멤버 함수에 대한 호출과 비 멤버 (무료) 함수에 대한 호출은 다음과 같습니다.

class A {
   void DoSomething() {
      m_counter=0;
      ...
      Twist(data); 
      ...
      Bend(data);
      ...
      if(m_counter>0) exit(0);
   }
   int m_couner;
   ...
}

그러나 그런 일이 수도 Twist클래스의 자매 멤버 함수입니다 ABend무료 기능입니다. 즉, Twist사용하고 수정할 수 있습니다 m_counerBend수 없습니다. 따라서 m_counter0으로 유지하려면 확인 Twist해야하지만 확인 할 필요는 없습니다 Bend.

따라서이를보다 명확하게 this->Twist나타 내기 위해 Twist멤버 함수 인 독자를 보여주기 위해 쓰거나 무료 인 ::Bend것을 나타 내기 위해 쓸 Bend수 있습니다. 아니면 둘다. 리팩토링을 수행하거나 계획 할 때 매우 유용합니다.


5

:: 네임 스페이스를 정의하는 연산자입니다.

예를 들어, using namespace std;코드에서 언급하지 않고 cout을 사용하려면 다음과 같이 작성하십시오.

std::cout << "test";

네임 스페이스가 언급되지 않은 경우 클래스는 글로벌 네임 스페이스에 속한다고합니다.


1

"::"는 범위 확인 연산자를 나타냅니다. 동일한 이름을 가진 함수 / 방법은 두 개의 다른 클래스로 정의 될 수 있습니다. 특정 클래스 범위 확인 연산자의 메소드에 액세스하는 데 사용됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.