2017-12-13 12 views
-1

C++에서 오버로드 연산자가 작동하는 방식을 배우려고합니다. 나는 +== 연산자를 구현하는 방법을 알아 냈지만 + 연산자로 고민 중입니다. 컴파일러는 연산자가 하나 또는 두 개의 인수 만 취할 수 있다고 알려줍니다. 결과를 제대로 반환하는 방법을 알아낼 수 없습니다.C++에서 LHS 인수를 수정하지 않고`+`연산자를 구현하는 방법은 무엇입니까?

인수로 취할 수있는 객체는 연산자의 LHS와 RHS가되지만, 결과를 저장하고 반환하는 클래스의 세 번째 인스턴스를 만들어야합니다. + 운영자가 LHS 또는 RHS 자체를 수정하지 않아야한다고 생각합니다.

또한 메서드 내에서 새 인스턴스를 만드는 것은 메서드가 완료된 후에 해당 개체가 제거되므로 작동하지 않습니다.

따라서 결과를 새로운 인스턴스에 올바르게 저장하려면 어떻게해야합니까?

이것은 내가 지금까지 뭘하려 : 당신은 operator+에서 *this을 반환하는

#include <iostream> 

class smallclass 
{ 
public: 
    smallclass(); 
    smallclass(int x); 

    smallclass& operator+=(smallclass&y); 
    smallclass& operator=(smallclass& y); 
    smallclass& operator+(smallclass& y); 
    int a; 

}; 

smallclass::smallclass() 
{ 

} 

smallclass::smallclass(int x) 
{ 
    this->a = x; 
} 


smallclass& smallclass::operator+=(smallclass&y) 
{ 
    this->a += y.a; 

    return *this; 
} 

smallclass& smallclass::operator=(smallclass& y) 
{ 
    int value = y.a; 
    this->a = value; 
    return *this; 
} 


smallclass& smallclass::operator+(smallclass& y) 
{ 
    int value = y.a; 
    this->a += value; 

    return *this; 
} 


int main() 
{ 
    smallclass a = smallclass(5); 
    smallclass b = smallclass(6); 

    std::cout << a.a << std::endl; 
    std::cout << b.a << std::endl; 
    // a = 5 
    // b = 6 

    a += b; 

    std::cout << a.a << std::endl; 
    std::cout << b.a << std::endl; 
    // a = 11 
    // b = 6 

    a = b; 

    std::cout << a.a << std::endl; 
    std::cout << b.a << std::endl; 
    // a = 6 
    // b = 6 

    smallclass c; 

    c = a + b; 

    std::cout << a.a << std::endl; 
    std::cout << b.a << std::endl; 
    std::cout << c.a << std::endl; 
    // a = 12 should be 6 
    // b = 6 
    // c = 12 

    return 0; 

} 
+2

우연히 아무 것도 수정하지 않도록'operator +'를'const'로 표시해야합니다. 개체의 복사본을 만들어 추가하고 반환하십시오. – tadman

+0

'operator ='는 값을 반환하지 않으므로 동작은 정의되지 않습니다. – PaulMcKenzie

+0

@PaulMcKenzie woops, 고정되어 있길 바랍니다. – JAD

답변

4

. 대신 새 결과가 들어있는 객체를 반환해야합니다. *this을 반환하면 x + y의 결과는 항상 x이며 이는 사실이 아닙니다. 결과는 xy과 구별되는 새로운 값입니다. 반환 값은 기존 인스턴스를 참조하지 않으므로 반환 유형은 참조가 아니어야합니다.

smallclass smallclass::operator+(smallclass& y) 
{ 
    smallclass result; 
    result.a = this->a + y.a; 
    return result; 
} 

정확한 내용은 const입니다. yconst 참조로 지정하면 운영자가 y을 수정하지 않는다는 것을 보증 할 수 있습니다. 전체 구성원 함수를 만들기 위해 동일하게 적용됩니다 const. 운영자가 this을 수정하지 않도록 클래스 사용자에게 보장합니다. 이 const이 없으면 const 인스턴스와 함께 운영자를 사용할 수 없습니다.

smallclass smallclass::operator+(const smallclass& y) const 
{ 
    smallclass result; 
    result.a = this->a + y.a; 
    return result; 
} 

더 관용적 접근 방식은 operator+=의 측면에서와 복사 생성자의 operator+를 구현하는 것입니다. 그렇게하면 자신을 반복 할 필요가 없습니다.

smallclass smallclass::operator+(const smallclass& y) const 
{ 
    smallclass result(*this); 
    result += y; 
    return result; 
} 

많은 운영자가이 작업을 수행 할 수 있습니다. 특히 비교 연산자는 모두 operator==operator<과 같이 두 가지 기본 비교만으로 구현할 수 있습니다.

+2

더 짧은 예제 :'return smallclass (* this) + = y; ' – PaulMcKenzie

+0

@PaulMcKenzie 아마 RVO를 막을 것입니다. – juanchopanza

3

operator+ 구현 표준 버전이있다 :

friend smallclass operator+ (smallclass op1, smallclass const& op2) { 
    op1 += op2; 
    return op1; 
} 

이 방법은 또한 기존의 operator+= 구현을 활용할 수 및 복사 생략을 활용한다.당신이 교환 법칙이 성립 또한 아래의 버전을 사용할 수 있습니다 왼쪽의 자동 변환을 억제하려면

: 추가가 교환 법칙이 성립하지 않는 경우

smallclass operator+ (smallclass rhs) const { 
    rhs += *this; 
    return rhs; 
} 

당신이 사용하는 거라고

smallclass operator+ (smallclass const& rhs) const { 
    return smallclass(*this) += rhs; 
} 

(마지막 버전은 하나의 사본을 완전히 삭제할 수 없습니다).

+0

lhs를'int'에서'smallclass'로 자동 변환하고 싶다고 가정 할 때 이것은 정식입니다. 그렇지 않다면 회원 방식이 더 적절합니다. –

+0

@ LokiAstari : rhs에서 자동 변환을 얻었으므로 또한 lhs에서도 자동 변환이 일관성있는 것으로 보입니다. –

+0

NRVO를 제외하고 "가능한 경우 복사 실행을 이용합니다". 따라서 LHS가 lvalue 인 경우 lvalue 참조를 가져 와서 함수의 본문에 사본을 만드는 버전보다 덜 적합 할 수 있습니다. – juanchopanza