문제

C ++ 번호와 같은 클래스에서 산술 연산자 과부하를 구현하기위한 표준 또는 권장 패턴이 있습니까?

C ++ FAQ에는 대부분의 문제를 피하는 예외 안전 할당 연산자가 있습니다.

class NumberImpl;

class Number {
   NumberImpl *Impl;

   ...
};

Number& Number::operator=(const Number &rhs)
{
   NumberImpl* tmp = new NumberImpl(*rhs.Impl);
   delete Impl;
   Impl = tmp;
   return *this;
}

그러나 다른 연산자 ( +, += 등)의 경우 내장 유형의 운영자처럼 행동하게하는 것 외에는 조언이 거의 없습니다.

이것들을 정의하는 표준 방법이 있습니까? 이것이 제가 생각해 낸 것입니다 - 내가 보지 못하는 함정이 있습니까?

// Member operator
Number& Number::operator+= (const Number &rhs)
{
    Impl->Value += rhs.Impl->Value; // Obviously this is more complicated
    return *this;
}

// Non-member non-friend addition operator
Number operator+(Number lhs, const Number &rhs)
{
     return lhs += rhs;
}
도움이 되었습니까?

해결책

Bjarne Stroustrup의 책에서 "C ++ 프로그래밍 언어"11 장 (운영자 과부하에 전념하는 사람)에서 그는 복소수 유형 (섹션 11.3)에 대한 수업을 겪습니다.

내가 그 섹션에서 알아 차리는 한 가지는 혼합 유형 작업을 구현한다는 것입니다. 이것은 아마도 모든 숫자 클래스에 예상 될 것입니다.

일반적으로, 당신이 가진 것은 좋아 보인다.

다른 팁

연산자를 작성할 때 고려해야 할 가장 큰 것은 회원 연산자가 왼쪽 매개 변수에서 변환을받지 않는다는 것입니다.

struct example {
  example(int);
  example operator + (example);
};

void foo() {
  example e(3), f(6);
  e + 4; // okay: right operand is implicitly converted to example
  e + f; // okay: no conversions needed.
  6 + e; // BAD: no matching call.
}

전환이 적용되지 않기 때문입니다 this 멤버 함수의 경우 이는 운영자로 확장됩니다. 운영자가 대신 한 경우 example operator + (example, example) 글로벌 네임 스페이스에서는 컴파일됩니다 (또는 통과 별 -ref가 사용 된 경우).

결과적으로 대칭 연산자가 좋아합니다 + 그리고 - 일반적으로 비회원으로 구현되는 반면, 복합 할당 연산자는 += 그리고 -= 회원으로 구현됩니다 (또한 데이터를 변경하여 회원이어야 함). 또한 코드 복제를 피하려면 대칭 연산자를 복합 할당 측면에서 구현할 수 있습니다 (컨벤션은 기능 내부의 임시를 권장하지만 코드 예에서와 같이).

컨벤션은 글을 쓰는 것입니다 operator+(const T&) 그리고 operator-(const T&) 측면에서 operator+=(const T&) 그리고 operator-=(const T&). 원시 유형을 추가하고 빼는 것이 합리적이라면 원시 유형에서 물체를 구성하는 생성자를 작성해야합니다. 컴파일러는 적절한 생성자를 암시 적으로 호출하기 때문에 과부하 된 연산자도 원시 유형에 대해 작동합니다.

자신을 언급했듯이, 필요하지 않은 기능에 액세스 권한을 부여하지 않아야합니다. 그러나 위의 코드에서 operator+(Number, const Number&) 나는 개인적으로 두 매개 변수를 구성하고 온도를 사용합니다. 나는 당신의 질문 아래의 주석자가 이것을 놓친 것은 놀라운 일이 아닙니다. 당신이하지 말아야 할 좋은 이유가 없다면, 놀라움과 속임수를 피하고 가능한 한 명백해야합니다.

코드가 다른 숫자 유형과 통합되도록하려면 std::complex, 주기적 변환을 조심하십시오. 즉, 공급하지 마십시오 operator OtherNumeric() 안에 Numeric 만약에 OtherNumeric a Numeric 매개 변수.

연산자 = x 측면에서 연산자 X를 작성하는 것은 전통적인 것입니다.
또한 표준 연산자의 모든 매개 변수는 Const입니다.

// Member operator
// This was OK
Number& Number::operator+= (Number const& rhs) 
{
    Impl->Value += rhs.Impl->Value; // Obviously this is more complicated
    return *this;
}

// Non-member non-friend addition operator
Number operator+(Number const& lhs,Number const& rhs)
{
     // This I would set the lhs side to const.
     // Make a copy into result.
     // Then use += add the rhs
     Number result(lhs);
     return result += rhs;
}

과제 연산자를 언급합니다.
그러나 당신은 사본 생성자를 언급하지 않았습니다. 당신의 수업은 원시 포인터의 소유권을 가지고 있기 때문에 이것을 정의 할 것으로 기대합니다. 할당 연산자는 전통적으로 사본 생성자 측면에서 작성됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top