81

멤버 함수로 선언 된 오버로드 된 연산자는 하나의 매개 변수 만 가질 수 있고 자동으로 전달 된 다른 매개 변수는 'this'포인터이기 때문에 비대칭이라고 읽었습니다. 따라서 이들을 비교할 기준은 없습니다. 반면에, 친구로 선언 된 과부하 연산자는 같은 유형의 두 가지 인수를 전달하기 때문에 대칭입니다. 따라서 비교할 수 있습니다. 제 질문은 포인터의 lvalue를 참조와 비교할 때 친구가 선호하는 이유는 무엇입니까? (비대칭 버전을 사용하면 대칭과 동일한 결과가 나타남) STL 알고리즘이 대칭 버전 만 사용하는 이유는 무엇입니까?연산자 오버로드 : 멤버 함수 대 비 멤버 함수?

+9

귀하의 질문은 이항 연산자에 대해 정말이다. 오버로드 된 모든 연산자가 단일 매개 변수로 제한되지는 않습니다.() 연산자는 여러 매개 변수를 사용할 수 있습니다. 반면 단항 연산자는 매개 변수를 가질 수 없습니다. –

+1

http://stackoverflow.com/a/4421729/103167 –

+2

[C++ FAQ : 연산자 오버로딩] (http://stackoverflow.com/questions/4421706/operator-overloading)에서 다룬 많은 주제 중 하나입니다 –

답변

101

연산자 오버로드 된 함수를 멤버 함수로 정의하면 컴파일러에서 s1 + s2과 같은 표현식을 s1.operator+(s2)으로 변환합니다. 즉, 연산자 오버로드 된 멤버 함수는 첫 번째 피연산자에서 호출됩니다. 이것이 회원 기능의 작동 방식입니다!

하지만 첫 번째 피연산자가 클래스가 아닌 경우 어떻게해야합니까? 첫 번째 피연산자가 클래스 유형이 아닌 연산자를 오버로드하려면, double을 사용하는 것이 좋습니다. 이렇게 쓰면 쓸 수 없습니다 10.0 + s2. 그러나 s1 + 10.0과 같은 표현식에 대해 연산자 오버로드 된 멤버 함수를 작성할 수 있습니다. 이 private 멤버에 액세스 할 필요가있는 경우

문제를 주문 해결하기 위해, 우리는 friend으로 연산자 오버로딩 기능을 정의합니다. 비공개 멤버에 액세스해야하는 경우에만 friend으로 지정하십시오. 그렇지 않으면 단순히 비회원이 아닌 회원 기능을 캡슐화를 향상!

class Sample 
{ 
public: 
    Sample operator + (const Sample& op2); //works with s1 + s2 
    Sample operator + (double op2); //works with s1 + 10.0 

    //Make it `friend` only when it needs to access private members. 
    //Otherwise simply make it **non-friend non-member** function. 
    friend Sample operator + (double op1, const Sample& op2); //works with 10.0 + s2 
} 

이 읽기 ​​:
A slight problem of ordering in operands
How Non-Member Functions Improve Encapsulation

+2

"개인 회원에 액세스해야하는 경우에만 '친구'로 지정하십시오. 액세서리를 쓰는 것을 지치거나 지치지 않을 때는 – badmaash

+4

@Abhi : 선택하십시오 : 향상된 캡슐화 대 게으른 쓰기 습관 – Nawaz

+0

알려진 바 있습니까? 전역'operator +()'가 단순히'return op2.operator + (op1); '이되게하여'friend' 키워드를 피할 수 없었던 경우 두 경우 모두 기본적으로 +는 입력 샘플을 수정하지 않고 대신에 새로운 샘플 값인'Sample'을 반환합니다. – matthias

14

그것의 필수적이지는 글로벌 연산자 과부하 부재 함수 연산자 과부하 사이로서 friend 연산자 과부하 부재 함수 연산자 과부하 구별. 당신은 클래스 형식이 이항 연산자의 바로 편에 표시되는 위치 표현을 허용 할 경우 글로벌 운영자 과부하를 선호하는

이유 중 하나입니다. 예를 들어

Foo f = 100; 
int x = 10; 
cout << x + f; 

만이 작동

푸 연산자 + (INT의 X, CONST 푸 & F)에 대한 글로벌 연산자 과부하가있는 경우;

글로벌 연산자 오버로드는 반드시 friend 함수 일 필요는 없습니다. 이는 Foo의 개인 회원에 액세스해야하는 경우에만 필요하지만 항상 그런 것은 아닙니다.

에 관계없이, Foo 경우에만 같은 멤버 함수 연산자 오버로드를했다 : 우리는 단지 Foo 인스턴스가 에 표시되는 위치 표현을 할 수있을 것입니다 ...

class Foo 
{ 
    ... 
    Foo operator + (int x); 
    ... 
}; 

는 플러스의를 왼쪽 운영자.

+1

+ 1은 회원 및 친구 기능보다는 회원 기능과 비회원 기능을 구별하기위한 것입니다. 오늘날 우리는 "전역 또는 네임 스페이스 범위"라고 말할 것입니다. –