접미사 a ++와 접두사 ++ a에 대해 두 가지 방법으로 operator ++를 ​​오버로드하는 방법은 무엇입니까?


답변:


165

다음과 같이 표시되어야합니다.

class Number 
{
    public:
        Number& operator++ ()     // prefix ++
        {
           // Do work on this.   (increment your object here)
           return *this;
        }

        // You want to make the ++ operator work like the standard operators
        // The simple way to do this is to implement postfix in terms of prefix.
        //
        Number  operator++ (int)  // postfix ++
        {
           Number result(*this);   // make a copy for result
           ++(*this);              // Now use the prefix version to do the work
           return result;          // return the copy (the old) value.
        }
}; 

15
이 코드는 또한 접두사 대 접미사 성능 차이를 보여줍니다. 반환하는 객체가 CPU 레지스터에 맞지 않으면 값 비싼 복사 작업을 수행하는 것입니다. 미리 증가 된 값을 사용해야하는 경우에는 괜찮지 만 그렇지 않은 경우 postfix가 훨씬 좋습니다. 예를 들어 일반적으로 사용하는 반복기는 다음과 같습니다. pos ++ 대신 for (pos = c.begin (); ...; ++ pos) {}
Eric

22
@Eric : 당신은 당신이 섞는 중간에있는 문장을 제외하고는 완전히 정정합니다. 더 나은 접두사.
Martin York

6
왜 않습니다 Number operator++ (int)int당신이 그것을 사용하지 않는 경우에도 매개 변수로?
숀 Letendre

10
@SeanLetendre : 실제로 int 매개 변수를 사용하지 않습니다. 가짜 매개 변수입니다. 그러나 C ++ 언어의 설계자는 접두사와 접미사 함수 정의를 구분하는 방법을 정의해야했습니다. 이것이 그들이 내린 디자인 결정입니다.
마틴 뉴욕

2
@EnricoMariaDeAngelis : 구문은 둘을 구별합니다. ++x접두사이고, 따라서 호출 operator++() 동안 x++후위이며, 따라서 호출operator++(int)
마틴 뉴욕

34

차이점은의 오버로드에 대해 선택한 서명에 있습니다 operator ++.

C ++ FAQ의이 주제에 대한 관련 기사에서 인용 됨 (자세한 내용은 여기로 이동) :

class Number {
  public:
    Number& operator++ ();     // prefix ++: no parameter, returns a reference
    Number  operator++ (int);  // postfix ++: dummy parameter, returns a value
};

추신 : 이 사실을 알았을 때 처음에 보았던 것은 더미 매개 변수 였지만 다른 반환 유형이 실제로 더 흥미 롭습니다. 그들은 왜 일반적인++x 것보다 더 효율적인 것으로 간주 되는지 설명 할 수 있습니다 .x++


17

유형 T에 대해 두 가지 (접두사 / 접미사) ++ 연산자를 오버로드하는 두 가지 방법이 있습니다.

개체 방법 :

"일반적인"OOP 관용구를 사용하는 가장 쉬운 방법입니다.

class T
{
    public :
        T & operator++() // ++A
        {
            // Do increment of "this" value
            return *this ;
        }

        T operator++(int) // A++
        {
           T temp = *this ;
           // Do increment of "this" value
           return temp ;
        }
} ;

개체 비 멤버 함수 :

이것은이를 수행하는 또 다른 방법입니다. 함수가 참조하는 객체와 동일한 네임 스페이스에있는 한 컴파일러가 처리 ++t ;하거나 t++ ;코딩 할 폰션을 검색 할 때 고려됩니다 .

class T
{
    // etc.
} ;


T & operator++(T & p_oRight) // ++A
{
   // Do increment of p_oRight value
   return p_oRight ;
}

T operator++(T & p_oRight, int) // A++
{
   T oCopy ;
   // Copy p_oRight into oCopy
   // Do increment of p_oRight value
   return oCopy ;
}

C ++ 관점 (C ++ 컴파일러 관점 포함)에서 이러한 비 구성원 함수는 동일한 네임 스페이스에있는 한 여전히 T 인터페이스의 일부라는 점을 기억하는 것이 중요합니다.

비 멤버 함수 표기법에는 두 가지 잠재적 이점이 있습니다.

  • T의 친구로 만들지 않고 코드를 작성하면 T의 캡슐화가 증가합니다.
  • 코드를 소유하지 않은 클래스 나 구조에도 적용 할 수 있습니다. 이것은 선언을 수정하지 않고 객체의 인터페이스를 향상시키는 비 간섭 적 방법입니다.

1

다음과 같이 선언하십시오.

class A
{
public:
    A& operator++();    //Prefix (++a)
    A operator++(int); //Postfix (a++)

};

적절하게 구현하십시오-모든 사람이 알고있는 일을 엉망으로 만들지 마십시오 (증가 후 사용, 사용 후 증가).


-2

늦었지만 같은 문제가 있었고 더 간단한 해결책을 찾았습니다. 오해하지 마십시오. 이것은 최상위 솔루션 (Martin York 게시) 과 동일한 솔루션입니다. 그것은 단지입니다 조금 더 간단. 조금만 요. 여기있어:

class Number
{
        public:

              /*prefix*/  
        Number& operator++ ()
        {
            /*Do stuff */
            return *this;
        }

            /*postfix*/
        Number& operator++ (int) 
        {
            ++(*this); //using the prefix operator from before
            return *this;
        }
};

위의 솔루션은 postfix 메서드에서 임시 객체를 사용하지 않기 때문에 조금 더 간단합니다.


6
이것은 표준이 아닙니다. 접미사 연산자 ++는 증분 이전이 아닌 값을 반환해야합니다.
Kuilin Li

이 대답은 틀 렸습니다. 임시가 필요합니다.
Rian Quinn
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.