멤버 액세스 연산자 오버로드-> ,. * (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
'IT' 카테고리의 다른 글
자바에서 자바 호출하기 (0) | 2020.07.22 |
---|---|
동일한 Jenkins 작업 공간에 여러 새 저장소를 체크 아웃하십시오. (0) | 2020.07.22 |
Git 브랜치를 로컬 및 원격으로 이름을 바꾸시겠습니까? (0) | 2020.07.22 |
null을 캐스팅하면 Convert.ToString (null)이 다른 값을 반환하는 이유는 무엇입니까? (0) | 2020.07.22 |
'초기 통신 패킷을 읽는 중'에서 MySQL 서버 연결이 더러워 짐, 시스템 오류 : 0 (0) | 2020.07.22 |