IT

멤버 액세스 연산자 오버로드-> ,. * (C ++)

lottoking 2020. 7. 22. 07:45
반응형

멤버 액세스 연산자 오버로드-> ,. * (C ++)


나는, 멤버 액세스 연산자를 제외한 대부분의 연산자 오버로딩을 이해 ->, .*, ->*

특히,이 연산자는 전달되는 것이 무엇입니까?

운영자 기능 (예 operator->(...):)은 어떤 멤버가 참조되고 어떻게 알 수 있습니까? 알 수 있습니까? 심지어 알아야?

마지막으로 할 때 const 고려 사항이 있습니까? 예를 들어 필요과 같은 것을 오버로드 할 수있는 operator[]일반적으로 const 버전과 non-const 버전이 있습니다. 멤버 액세스 연산자에는 const 및 non-const 버전이 필요합니까?


->

이것은 정말 까다로운 유일한 것입니다. 비 정적 멤버 함수 인수를 사용하지 않습니다. 반환 값은 멤버 조회를 수행하는 데 사용됩니다.

리턴 값이 포인터가 아닌 클래스 유형의 다른 오브젝트 인 경우에는 멤버 검색도 operator->함수에 의해 처리 됩니다. "드릴 다운 동작"이라고합니다. 언어 operator->는 마지막 호출이 포인터를 반환 할 때까지 호출을 연결합니다 .

struct client
    { int a; };

struct proxy {
    client *target;
    client *operator->() const
        { return target; }
};

struct proxy2 {
    proxy *target;
    proxy &operator->() const
        { return * target; }
};

void f() {
    client x = { 3 };
    proxy y = { & x };
    proxy2 z = { & y };

    std::cout << x.a << y->a << z->a; // print "333"
}

->*

이 특별한 것이 특별한 점에서 까다 롭습니다. 비 오버로드 버전은 클래스 요구에 유형과 오른쪽에 멤버 유형 포인터의 요구에 대한 포인터의 클래스로한다. 그러나 더 많은 것이 걸리면 원하는 인수를 취하고 원하는 것을 반환 할 수 있습니다. 비 정적 멤버 일 필요도 없습니다.

즉, 이와 같은 단지 일반적인 이진 연산자 +, -/. 참조 : 무료 연산자-> * 등장가 악한가?

.*.

오버로드 할 수 없습니다. 유형일 때 이미 내장 된 의미가 있습니다. 할 수있는 것이 다소 합리적이지만 언어 설계위원회는 유용 할 생각하는 것이 어쩌면 혼란 스럽다고 결정했습니다.

오버로드 ->, ->*, ., 및 .*표현이 정의되지 않은 될 경우에만 경우에 입력 입력 할 수 있습니다, 그것은 전혀 오버로드로 유효한 것입니다 표현의 의미를 변경하지 않을 수 있습니다 .


연산자->는 특별합니다.

"비정형적인 추가 제약이 있습니다 포인터 역 참조 연산자가있는 객체 (또는 객체에 대한 참조)를 반환하거나 포인터 역 참조 연산자 화살표 가 가리키는 항목을 선택하는 데 사용할 수있는 포인터를 반환해야합니다 .." 브루스 에켈 (Bruce Eckel) : 생각하는 CPP Vol-one : 운영자->

편의를 위해 추가 기능이 제공 전화하지 않습니다.

a->->func();

간단하게 할 수 있습니다.

a->func();

따라서 연산자->가 다른 연산자 등장과.


멤버 액세스를 오버로드 할 수 없습니다 .(예 : 두 번째 부분 ->). 그러나 단항 참조 참조 연산자 *(즉, 작업의 첫 번째 부분)에 작업을 걸 수 있습니다 ->.

는 C ++ ->연산자는 기본적으로 두 단계의 결합이며, 당신이 생각하면이 분명하다 x->y동일합니다 (*x).y. C ++를 사용하면 클래스의 인스턴스 일 (*x)때 파트 로 수행 할 작업을 사용자 정의 할 수 있습니다 x.

->오버로딩 의 의미 는 C ++에서 일반 포인터를 반환하거나 (포인트 객체를 찾는 데 사용됨)이 클래스가 ->연산자를 제공하는 경우 다른 클래스의 인스턴스를 반환 할 수 있기 때문에 다소 이상합니다 . 두 번째 경우에 참조 해제 된 개체에 대한 검색이이 새 인스턴스에서 계속됩니다.


->지적되는 내용 회원 모르는 연산자, 그것은 단지의 실제 멤버 액세스를 수행하는 객체를 제공합니다.

또한 const 및 non-const 버전을 제공 할 수없는 이유가 없습니다.


operator-> () (여기에 인수가 전달되지 않음)를 오버로드 할 때 컴파일러는 실제로 유형에 대한 실제 포인터를 반환 할 때까지-> 재귀 적으로 호출합니다. 그런 다음 올바른 구성원 / 방법을 사용합니다.

예를 들어 실제 포인터를 캡슐화하는 스마트 포인터 클래스를 만드는 데 유용합니다. 오버로드 된 operator->가 호출되고, 그것이하는 일 (예 : 스레드 안전을위한 잠금)을 수행하고 내부 포인터를 반환 한 다음 컴파일러는이 내부 포인터에 대해->를 호출합니다.

constness에 관해서는 주석 및 기타 답변에서 답변되었습니다 (둘 다 제공 할 수 있고 제공해야합니다).

참고 URL : https://stackoverflow.com/questions/8777845/overloading-member-access-operators-c

반응형