답변:
foo->bar
동등한 규칙 (*foo).bar
은 내장 연산자에만 적용됩니다.
단항 operator *
에 포인터 역 참조 시맨틱이 항상있는 것은 아닙니다. 매트릭스 전치, 0 개 이상의 파서 일치 또는 거의 모든 것을 의미하는 라이브러리를 만들 수 있습니다.
단항에 과부하가 걸리는 operator *
것이 operator ->
의미가없는 의미론으로 요청하지 않은 것을 갑자기 얻는 다면 언어가 더 귀찮게 될 것입니다 .
operator ->
별도의 과부하가 가능하므로 원하는 경우 최소한의 노력으로 과부하를 걸 수 있습니다.
또한 이러한 과부하 operator ->
에는 체인 중 하나가 원시 포인터를 반환 할 때까지 호출을 자동으로 연결하는 것과 같이 다소 흥미로운 속성이 있습니다 . 이는 스마트 포인터 및 기타 프록시 유형에 매우 유용합니다.
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <string>
#include <iostream>
#include <ostream>
struct Foo
{
boost::shared_ptr<std::string> operator -> () const
{
return boost::make_shared<std::string>("trololo");
}
};
int main()
{
Foo foo;
std::cerr << foo->size() << std::endl;
}
->
무언가에 대한 원시 포인터를 얻을 때까지 연산자 체인을 사용하여 그 멤버를 역 참조하고 액세스하는 방법을 보여줍니다. operator->가 연결되지 않으면 shared_ptr이 원시 포인터가 아니기 때문에 예제가 잘못 구성됩니다.
A->B
최대 1 번의 추가 호출에서 구문 체인을 사용하는 것은 올바르지 않습니다 . C ++-> 이진 구문이 실제로하는 것은 객체를 opeartor->
직접 호출하는 것이 아니라 유형을보고 A
원시 포인터인지 확인하는 것입니다. 만약 그것을 ->
거부하고 실행 B
하면, 그렇지 않으면 객체를 호출하고 operator->
, 결과를 거부합니다 (기본 원시 포인터 또는 다른 것을 사용 하여 결과에 operator->
실행)B
x->m
로 해석 됨을 나타냅니다 (x.operator->())->m
. LHS가 operator->
다시 과부하가 적절한 경우이 프로세스는 일반적인 (*x).m
효과가 5.2.5 / 2가 될 때까지 반복 됩니다.
"C ++ 프로그래밍 언어"는 이러한 연산자가 서로 다르기 때문에 다음과 같이 말합니다.
당신이 더 많은 이러한 연산자 중 하나 이상 제공하는 경우, 그것은을 확인하는 것이 현명하다 것처럼, 등가를 제공하는 것이 현명 수 있습니다
++x
와x+=1
같은 효과를 가지고x=x+1
간단한 변수에 대한x
몇 가지 클래스를 경우 ++, + =, =, 및 +가 제공됩니다.
따라서 언어 디자이너는 항상 동일한 것을 원한다고 가정하지 않고 서로 다른 과부하 지점을 원할 수 있으므로 별도의 과부하 지점을 제공 한 것 같습니다 .
의 과부하 때문에 일반적으로 C ++는 찬성의 유연성으로 설계 *
하고 ->
별도입니다. 그렇게하는 것은 매우 드문 일이지만, 충분히 과도하게 원한다면 완전히 다른 일을하기 위해 과부하를 작성할 수 있습니다 (예 : C ++ 내부에서 구현 된 도메인 특정 언어에 적합 할 수 있음).
즉, 반복자 는 두 가지 사용법을 모두 지원합니다. 고대 구현에서는. (*iter).whatever
대신 필요한 라이브러리를 찾을 수 iter->whatever
있지만, 그렇다면 언어의 특성이 아닌 구현의 버그입니다. 모든 표준 컨테이너 / 알고리즘 / 반복기를 구현하는 데 필요한 작업량을 감안할 때 일부 초기 릴리스가 다소 불완전한 것은 놀라운 일이 아니지만 실제로 그런 식으로 의도 된 것은 아닙니다.
(*i).m
은 유효한 반복자 가 i->m
동일한 의미로 지원해야합니다 .