'::'을 '로 바꾸십시오. 'C ++로 모호성을 만드시겠습니까?


95

C ++에서 연산자 ::는 네임 스페이스 또는 클래스의 클래스, 함수 및 변수에 액세스하는 데 사용됩니다.

언어 명세를 사용하는 경우 .대신 ::인스턴스 변수 다음 객체 / 방법을 액세스 할 때와 같이 너무 이러한 경우에서와 함께 존재하지 않는 것을 원인 가능한 모호함 ::?

C ++에서 유형 이름 인 변수 이름을 허용하지 않기 때문에 발생할 수있는 경우를 생각할 수 없습니다.

설명 : 나는 왜 그것이 효과 ::가 있었을 지에 대해 왜 선택 되었는지 묻지 않고 .있습니까?


의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
Samuel Liew

답변:


124

C ++가 기존 C 코드와 대부분 호환되도록 (오브젝트 이름과 구조체 태그 사이의 이름 충돌을 허용 함) 시도하기 때문에 C ++은 클래스 이름과 객체 이름 사이의 이름 충돌을 허용합니다.

의미하는 것은:

struct data {
    static int member;
};

struct data2 {
    int member;
};

void f(data2& data) {
    data.member = data::member;
}

합법적 인 코드입니다.


11
제목의 질문에 대한 대답은 그렇습니다. 그렇지 않습니까?
Enrico Maria De Angelis

2
@EnricoMariaDeAngelis 그렇게 간단하지 않습니다. C ++은 Java 나 C #과 같은 완전히 새로운 언어로 개발되었으므로 모호성을 피할 수 있습니다. 그러나 C ++은 "클래스가있는 C"로 개발되었으므로 그렇지 않습니다. "예, 그것은 "정답이지만, 다른 질문.
키트.

대기, 할당 라인은 퍼팅 것으로 표시되지 .또는 ::(다른 효과가 같은 두 개의 "단어"사이에 data.member받는 의미 memberdata클래스의 객체 data2반면, data::member받는 사람을 의미 member클래스의 data)?
Enrico Maria De Angelis

1
그렇습니다. 그러나 언어 디자이너가 자랑스럽게 여기는 것은 아닙니다. 호환성 결정의 유물 일뿐입니다.
키트.

좋아, 나는 C ++가 오늘날 어떻게 지금까지 왔으며 (또한) C ++이 C ++에서 개발되었을 당시의 C에 달려 있다는 것을 이해합니다. 그러나 C ++을 그대로 이야기하고 그 이유를 그대로두고 모든 ::것이로 변경 되면 모호성 이 .있습니다. 어떤 식 으로든 당신은 이미 예라고 대답했습니다 . 난 그냥 당신에게 첫 번째 의견을 위반 할 수 없습니다. 어쩌면 내 수준으로 인해 그 댓글이 연기가 나게 보일 수도 있습니다.
Enrico Maria De Angelis

37

둘 다 유효하지만 다른 객체를 참조하는 예 :

#include <iostream>

struct A {
    int i;
};

struct B {
    int i;
    A B;
};

int main() {
    B x {0, 1};
    std::cout << x.B.i << '\n';
    std::cout << x.B::i << '\n';
}

coliru에서 라이브를 참조하십시오 .


그리고 이것은 다른 디자인 결정으로 쉽게 해결할 수 없었 습니다!
user253751

7

차이가 존재 a::b하고 a.b여기서 ::것을 의미 a는 네임 또는 유형 이름은 즉, 네임 스페이스로하는 방법을 사용 하였다. C ++이 비가 상 복수 상속을 지원하고 변수가 유형과 동일한 이름을 가질 수있는 경우 잘못된 객체를 참조 할 가능성이 줄어 듭니다. 템플릿 메타 프로그래밍에 필요합니다.

또 다른 예는 클래스 B와 관련하여 &B::foovs &B.foo입니다.


2

@Deduplicator 예제를 확장하자 :

#include <iostream>

struct A {
    int i;
};

struct B : public A {
    int i;
    A A;
};

int main() {
    B x {1, 2};
    std::cout << x.i << '\n';
    std::cout << x.B::i << '\n';  // The same as the line above.
    std::cout << x.A.i << '\n';
    std::cout << x.A::i << '\n';  // Not the same as the line above.
}

Coliru Viewer에서 라이브

::의 도움으로 구별 할 가능성이 없는데, 우리가 접근하고자하는 멤버라면, 같은 이름으로 부모 클래스에 선언 된 멤버에 접근하는 것은 불가능합니다.


A A(유형 이름이기도 한 변수 이름)은 C ++에서 유효하지 않으므로이 예제는 현재 작동하지 않습니다.
Jimmy RT

1
@ JimmyR.T. Coliru Viewer에는 실무 예제가 있습니다. 표준의 단락으로 진술을 확인하십시오.
SM

저주받은 상속 다이아몬드를 다른쪽에 같은 것으로 추가하면 C ++에서 가능한 정신 분열증 명명의 정점이 될 것입니다.
Swift-Friday Pie
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.