수정해야 할 클래스에서이 코드 줄을 찾았습니다.
::Configuration * tmpCo = m_configurationDB;//pointer to current db
그리고 이중 콜론이 클래스 이름 앞에 붙는 것이 정확히 무엇을 의미하는지 모르겠습니다. 그것 없이는 읽을 것입니다 : tmpCo
클래스의 객체에 대한 포인터 선언은 Configuration
…하지만 이중 이중 콜론은 나를 혼란스럽게합니다.
나는 또한 발견했다 :
typedef ::config::set ConfigSet;
답변
이렇게하면 현재있는 네임 스페이스에서 시작하는 대신 전역 네임 스페이스에서 확인이 수행됩니다. 예를 들어, 두 개의 다른 클래스가있는 경우 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
.
답변
::
운영자는 범위 해상도 사업자라고하고 범위를 해결 그냥 것을 수행한다. 따라서 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;
}
답변
이미 합리적인 답변이 많이 있습니다. 일부 독자에게 도움이 될 수있는 유추를 살펴 보겠습니다. 실행하려는 프로그램의 경로를 검색 할 때 ::
파일 시스템 디렉토리 구분 기호 ‘ /
‘ 와 매우 유사합니다 . 치다:
/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 namespace
s를 많이 사용한 경우 모호성을 만듭니다 .이 공간에서 할 수있는 최악의 일은 허용입니다.using namespace
임의로 많은 양의 직접 및 간접 클라이언트 코드가 사용할 네임 스페이스 및 모호성을 관리하는 방법에 대한 자체 결정을 내릴 수 없도록 헤더의 범위를 벗어나기 위해 헤더에 있습니다.
따라서 선행 ::
은 C ++ 프로그래머 도구 상자에 알려진 충돌을 적극적으로 명확하게하거나 미래의 모호함을 제거 할 수있는 도구 중 하나입니다.
답변
::
범위 확인 연산자입니다. 무언가의 범위를 지정하는 데 사용됩니다.
예를 들어 ::
다른 모든 네임 스페이스 외부의 전역 범위 만 있습니다.
some::thing
다음 방법 중 하나로 해석 될 수 있습니다.
some
A는 공간 (글로벌 범위, 또는 현재 하나 이상의 외측 범위) 및thing
A는 입력 하는 기능 , 객체 또는 중첩 된 공간 ;some
현재 범위에서 사용할 수 있는 클래스 이며 클래스thing
의 멤버 객체 , 함수 또는 유형 입니다some
.- 클래스의 멤버 함수 ,
some
될 수 기본형 전류 형 (또는 전류 타입 자체) 및thing
그 다음,이 클래스의 하나의 부재, 인 형태 , 기능 또는 목적 .
에서처럼 중첩 범위를 가질 수도 있습니다 some::thing::bad
. 여기서 각 이름은 유형, 객체 또는 네임 스페이스 일 수 있습니다. 또한 마지막 bad
것은 함수일 수 있습니다. 함수는 내부 범위 내에서 아무것도 노출시킬 수 없으므로 다른 함수는 할 수 없습니다.
따라서 예제로 돌아 가면 ::thing
전역 범위에서 유형, 함수, 객체 또는 네임 스페이스 만 될 수 있습니다.
사용하는 방식은 (포인터 선언에서 사용되는) 전역 범위의 유형임을 제안합니다.
이 답변이 스코프 해상도를 이해하는 데 도움이되도록 완전하고 정확하기를 바랍니다.
답변
::
네임 스페이스 나 클래스에 무언가 (변수, 함수, 클래스, typedef 등)를 연결하는 데 사용됩니다.
앞에 왼쪽이 없으면 ::
전역 네임 스페이스를 사용하고 있다는 사실을 강조합니다.
예 :
::doMyGlobalFunction();
답변
해당 범위 확인 연산자, 숨겨진 전역 이름은 범위 확인 연산자 ::
를 사용하여 참조 할 수 있습니다 .
int x;
void f2()
{
int x = 1; // hide global x
::x = 2; // assign to global x
x = 2; // assign to local x
// ...
}
답변
(이 답변은 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
클래스의 자매 멤버 함수입니다 A
및 Bend
무료 기능입니다. 즉, Twist
사용하고 수정할 수 있습니다 m_couner
와 Bend
수 없습니다. 따라서 m_counter
0으로 유지하려면 확인 Twist
해야하지만 확인 할 필요는 없습니다 Bend
.
따라서이를보다 명확하게 this->Twist
나타 내기 위해 Twist
멤버 함수 인 독자를 보여주기 위해 쓰거나 무료 인 ::Bend
것을 나타 내기 위해 쓸 Bend
수 있습니다. 아니면 둘다. 리팩토링을 수행하거나 계획 할 때 매우 유용합니다.