왜 '.'를 오버로드 할 수 없습니까? C ++의 연산자?


79

.NET Framework를 오버로드 할 수 있으면 매우 유용 할 것입니다. C ++에서 연산자를 사용하고 개체에 대한 참조를 반환합니다.

당신은 오버로드 할 수 operator->operator*하지만operator.

이에 대한 기술적 이유가 있습니까?


4
'.'을 재정의하려는 경우에 대한 예를 제공 할 수 있습니까? 운영자?
Toon Krijthe

4
일반적으로 사용 사례는 "스마트 참조"입니다. 일종의 프록시.
ddaa

2
@Gamecat : 읽기를 통해 제안은 오버로드 할 수있는 기능을 추가 operator.하고 operator.*그것은 몇 가지 예를 보유하고 있습니다.
Mankarse

1
@ToonKrijthe 공간 .은 허용되므로 내적을 matrix1 . matrix2.
mwcz

답변:


62

Bjarne Stroustrup의이 인용문을 참조하십시오 .

운영자 . (점)은 원칙적으로->에 사용 된 것과 동일한 기술을 사용하여 오버로드 될 수 있습니다. 그러나 이렇게하면 작업이 개체 오버로딩을위한 것인지에 대한 질문으로 이어질 수 있습니다. 또는에서 참조하는 객체. 예를 들면 :

class Y {
public:
    void f();
    // ...
};

class X {    // assume that you can overload .
    Y* p;
    Y& operator.() { return *p; }
    void f();
    // ...
};

void g(X& x)
{
    x.f();    // X::f or Y::f or error?
}

이 문제는 여러 가지 방법으로 해결할 수 있습니다. 표준화 당시에는 어떤 방법이 가장 좋은지 분명하지 않았습니다. 자세한 내용은 The Design and Evolution of C ++를 참조하십시오 .


내 대답에 TDaEoC ++의 전체 인용문.
ddaa

15
나는 표절 / 색칠하기 위해 이것을 투표하고 싶습니다. 인용 할 때는 그대로 인용하고 조정하지 마십시오. 그리고 견적 형식을 사용하십시오.
Sebastian Mach

2
예제는보다 신중한 프로그래밍이 필요함을 가리키는 오버로드 해결 모호성 일뿐입니다 (참조 : stackoverflow.com/questions/13554606/… )이 상황은 오버로드를하지 않는 이유가되어서는 안됩니다operator .
slashmais

아니오 @slashmais의 정당성 operator.과 명시 평행하다 operator->. 그리고 어떻게 과부하 해결을 할 수 있습니까?
curiousguy 2015-08-26

나중에 Bjarne Stroustrup은 operator dot 에 찬성 했고 심지어는 (아직) 수용되지 않은 제안을 밀어 냈습니다 : http://www.open-std.org/jtc1/sc22/wg21/ 문서 / 논문 / 2015 / n4477.pdf - 이미 질문에 주석으로 @emlai 추가
아미르 Kirsh

52

Stroustrup은 C ++는 확장 가능해야하지만 변경 가능한 언어는 아니어야한다고 말했습니다.

도트 (속성 액세스) 연산자가 언어의 핵심에 너무 가까워서 오버로딩을 허용하지 않는 것으로 나타났습니다.

참조 디자인 및 C의 진화 ++ , 242 페이지, 섹션 11.5.2 스마트 참조를 .

operator의 과부하를 허용하기로 결정했을 때 ->자연스럽게 operator. 가 비슷하게 오버로드 될 수 .

그 당시 나는 다음과 같은 주장이 결정적이라고 생각했다. If objis a class object then obj.mhas a meaning for every member mof the object 's class. 우리는 내장 연산을 재정의함으로써 언어를 변경 가능하게 만들지 않으려 고합니다 (비록 =절박하고 단항의 경우 규칙을 위반하지만 &).

.클래스 에 대한 오버로드를 허용하면 정상적인 방법으로의 X멤버에 액세스 할 수 없습니다 X. 우리는 포인터를 사용해야 ->하지만, ->&도 다시 정의되어있을 수 있습니다. 나는 변경 가능한 언어가 아닌 확장 가능한 언어를 원했습니다.

이러한 주장은 중요하지만 결정적이지는 않습니다. 특히 1990 년에 Jim Adcock은 운영자가 . 정확히 운영자 와 똑같은 방식으로 운영자의 과부하를 허용하도록 제안했습니다 ->.

이 인용구의 "I"는 Bjarne Stroustrup입니다. 당신은 그것보다 더 권위있을 수 없습니다.

C ++를 정말로 이해하고 싶다면 ( "왜 이런 식입니까")이 책을 반드시 읽어야합니다.


28

Stroustrup 은이 질문에 대한 답을 가지고 있습니다 .

운영자 . (점)은 원칙적으로->에 사용 된 것과 동일한 기술을 사용하여 오버로드 될 수 있습니다. 그러나 이렇게하면 작업이 개체 오버로딩을위한 것인지에 대한 질문으로 이어질 수 있습니다. 또는에서 참조하는 객체. 예를 들면 :

class Y {
public:
    void f();
    // ...
};
class X {   // assume that you can overload .
    Y* p;
    Y& operator.() { return *p; }
    void f();
    // ...
};
void g(X& x)
{
    x.f();  // X::f or Y::f or error?
}

이 문제는 여러 가지 방법으로 해결할 수 있습니다. 표준화 당시에는 어떤 방법이 가장 좋은지 분명하지 않았습니다. 자세한 내용은 D & E를 참조하십시오 .


1
Anton의 대답에 대한 내 의견보기
slashmais

1

연산자 함수 호출의 내부 메커니즘을 살펴보면 이해하기가 매우 쉽습니다. 클래스 콤플렉스는 실수 부분에 대해 두 개의 멤버 r과 허수 부분에 대해 i를 가질 수 있다고 가정 해보십시오. 말 복잡한 C1 (10, 20), C2 (10,2)을 // 우리는 클래스 내에서 이미 두 개의 인수 생성자가 가정합니다. 이제 C1 + C2 를 문으로 작성하면 컴파일러는 복소수에서 + 연산자의 오버로드 된 버전을 찾으려고합니다. 이제 우리는 내가 + 연산자를 오버로드한다고 가정하므로 C1 + C2는 내부적으로 c1.operator + (c2) 로 번역됩니다. 이제 당분간 '.'을 오버로드 할 수 있다고 가정합니다. 운영자. 이제 다음 호출 C1.disp () // 복잡한 객체의 내용 표시 이제 내부 표현으로 표현해보십시오. C1.operator. (------) , 완전히 지저분한 일이 만들어졌습니다. 이것이 우리가 '.'를 오버로드 할 수없는 이유입니다. 운영자


1
어떤 사람들은 내부에 과부하가 호출해서는 안 번역 말operator.
curiousguy

이것이 어떻게 유용하고 그렇게 지저분하지 않을 수 있는지에 대한 C ++ 제안을 참조하십시오. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4477.pdf
Amir Kirsh
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.