2010-07-06 9 views
4

언어 디자인 관점에서 어떤 연산자 유형이 연산자 오버로드를 지원합니까?연산자 오버로드

무엇이 찬성입니까 & (있는 경우)?

+1

가능한 복제 http://stackoverflow.com/questions/77718 – krock

답변

16

편집 :std::complex는 연산자 오버로딩의 "좋은 사용"에 대한 std::string보다 훨씬 더 좋은 예는 언급하고있다, 그래서 그뿐만 아니라의 예를 포함하고있다 : 제외

std::complex<double> c; 
c = 10.0; 
c += 2.0; 
c = std::complex<double>(10.0, 1.0); 
c = c + 10.0; 

에서 생성자 구문은 다른 내장 유형과 비슷하게 보이고 작동합니다.


기본 제공 기능은 기본 제공 유형과 같은 새로운 유형을 만들 수 있다는 것입니다. 이에 대한 좋은 예가 std::string (더 좋은 예는 위 참조)입니다. 라이브러리에서 구현되며 기본 유형이 아닙니다. 그러나 다음과 같이 쓸 수 있습니다 :

std::string s = "hello" 
s += " world"; 
if(s == "hello world") { 
    //.... 
} 

단점은 남용하기 쉽다는 것입니다. 연산자 오버로딩의 선택이 잘못되면 실수로 비효율적이거나 불분명 한 코드가 발생할 수 있습니다. std::listoperator[] 인 경우를 상상해보십시오.당신은 쓰고 유혹 할 수있다 :

for(int i = 0; i < l.size(); ++i) { 
    l[i] += 10; 
} 

O (N^2) 알고리즘의 그! 아야. 다행히 효율적인 작업이라고 가정하기 때문에 std::listoperator[]이 아닙니다.

+0

+1 좋은 목록 예. – martiert

+1

문자열에 대해 연산자 +를 정의하는 명백한주의 사항이있는 "좋은 예"는 ... 9 – jalf

+2

왜 이것이 좋은 예입니까? 'operator +'는 모든 내장 유형에 대해 교환 가능하지만'std :: basic_string '에 대해서는 교환 가능하지 않기 때문에 연산자 오버로딩의 남용이라고 말할 수 있습니다. 'std :: complex'가 더 좋은 예가 될 수 있습니다. – Philipp

6

장점 : 더 쉽게 읽을 수있는 코드로 끝낼 수 있습니다.

BigDecimal a = x.add(y).divide(z).plus(m.times(n)); 

BigDecimal a = ((x + y)/z) + (m * n); // Brackets added for clarity 

단점으로 읽기 쉽게입니다 : 소수의 사람들이 있다는 주장이 호출되고 있는지 알려 어렵습니다. 나는 그들 모두가 무엇인지 기억할 수 있지만, C++,

a = b[i]; 

7 개 사용자 정의 작업을 수행 끝낼 수있는 형식의 성명에서 그 기억 보인다. 예제에서는 약간 "꺼져"있을지 모르지만 원리는 옳습니다. 연산자 오버로딩과 사용자 정의 변환은 코드를 "숨길"수 있습니다.

+0

내가 말할 수있는 한 한 가지. 할당 연산자를 호출해야합니다. 물론, 원하는만큼 많은 다른 작업을 호출 할 수 있습니다. (반면에'A a = b'는 복사 생성자를 호출했을 것입니다.) – jalf

+0

변환을 적용 할 수도 있습니다. – visitor

+0

@visitor : 나는 색인 생성을 놓쳤다 고 생각합니다 :) 편집 할 것입니다 ... –

13

초기 드라이버는 일반적으로 수학입니다. 프로그래머는 a + b을 쓰고 벡터를 덧셈하고 벡터를 곱하기 위해 M * v 벡터를 덧붙이고 싶습니다.

이보다 훨씬 넓은 범위가 있습니다. 예를 들어 스마트 포인터는 일반적인 포인터처럼 구문 적으로 보입니다. 스트림은 유닉스 파이프처럼 보일 수 있으며 다양한 사용자 정의 데이터 구조는 마치 배열 인 것처럼 사용할 수 있습니다 (문자열을 인덱스로 사용해도!).

오버로드의 일반적인 원칙은 라이브러리 구현자가 언어를 원활하게 향상시킬 수 있도록하는 것입니다. 이것은 힘과 저주입니다. 그것은 언어를 상자 밖의 것보다 더 풍부하게 보이게하는 매우 강력한 방법을 제공하지만 악용에 매우 취약합니다 (다른 많은 C++ 기능보다 더 많이).

+0

당신이 힘과 저주라고 말하면 동의하지만 프로그래밍의 모든 힘은 저주입니다. 무엇이든 오용 될 수 있습니다. 연산자 오버로딩을 통해 프로그래머는 더 나쁜 인터페이스를 만들 수 있으므로 프로그래머가 잘못된 변수 이름을 만들거나 프로그래머가 객체 컨텍스트를 엉망으로 만들거나 디버거를 사용하여 프로그래머를 덜주의 깊게 만들거나 IDE에서 프로그래머를 게으르게 만들 수 있습니다. 나는 모든 것들이 프로그래밍에 긍정적 인 영향을 미친다고 생각하지만, 그들은 모두 오용 될 가능성이있다. –

+0

@B T : 이들은 모두 모성 선언문입니다. 절대적으로 어떤 것이 힘과 저주로 특징 지어 질 수 있다면 그 문구는 무의미 해집니다. 분명히, 내 의도는 연산자 오버로드가 특히 변수를 설정하거나 배열을 만들거나 루프에서 반복하거나 함수를 호출 할 수있는 정도까지 남용하는 경향이 있다는 개념을 전달하는 것이 었습니다. –

1

구문 (예 : C++의 스트림)으로 흥미로운 트릭을 만들 수 있으며 코드를 간결하게 만들 수 있습니다. 그러나 디버깅 및 이해가 어려운 코드를 작성하는 효과를 얻을 수 있습니다. 당신은 일종의 다양한 종류의 객체의 다양한 연산자의 효과에 대해 항상 경계해야합니다.

+1

C++ '<<' and '>>'연산자는 연산자 오버로딩의 표준 * 나쁜 예입니다. 하천에 대한 그들의 사용은 원래의 의미와 아무런 관련이 없습니다. – dan04

+0

@ dan04 : 반면에, '<<' and '>>은 운영자가 직접 만든 아주 애처 롭다. 그들은 C와 ilk에 익숙하지 않은 사람들에게는 의미가 없으며, 내장 된 유형의 서브 세트에 대해서만 정의되며, 결과에 대해 작업하는 유형에 대해서조차도 항상 잘 정의되지는 않습니다. 그것들은 나쁜 오버로딩을 설명 할 수 있지만, 때로는 가이드 라인이 때때로 좋은 용도로 구부러 질 수있는 이유를 설명합니다. –

0

연산자 오버로딩은 일종의 메서드/함수 오버로드로 간주 할 수 있습니다. 객체 지향 언어에서 다형성의 일부입니다. 오버로드와

, 객체의 각 클래스는 쉽게

2 + 1으로는 복소수 클래스, 단지 말, 사용하는 클래스가 더 자연 만들 원시 형처럼 작동합니다. 복합체 (1,2i) + 복합체 (2,3i)는 복합체 (3,5i)를 산출합니다. 5 + Complex (3, 2i)는 Complex (8, 2i)를 산출합니다. 복소수 (2, 4i) + -1.8은 복소수 (0.2, 4i)를 산출합니다.

이렇게하면 클래스를 사용하는 것이 훨씬 쉽습니다. 연산자 오버로딩이 없다면 클래스 메서드를 사용하여 '추가'를 표시하고 표기법을 어색하게 만들어야합니다.

연산자 오버로딩은 신중하게 정의해야합니다. 그렇지 않으면 혼란이 온다. 예를 들어 '+'연산자는 배열이나 텍스트의 숫자, 시간, 날짜 또는 연결을 추가하는 것이 자연 스럽습니다. Mouse 또는 Car 클래스에 '+'연산자를 추가하는 것은 의미가 없습니다. 때로는 일부 과부하가 일부 사람들에게는 자연스럽게 보이지 않을 수도 있습니다. 예를 들어, Array (1,2,3) + Array (3,4,5). 일부는 Array (4,6,8)를 기대하지만 일부는 Array (1,2,3,3,4,5)를 기대합니다.