C++ 오버로딩한 연산자를 조합하여 사용한 경우 g++ 컴파일 에러 관련 질문 드립니다.


수업 중 복소수를 클래스로 구현하고 연산자 오버로딩을 사용하여 간단한 테스트를 돌리는 프로그램을 구현하는 과제가 있었습니다. 그 중 전역 함수 오버로딩을 한 **(multiple)연산자와 *++(후위 증감 연산자)**를 같이 쓰는 테스트케이스가 있었는데, Visual Studio로는 컴파일에 성공하고 정상적으로 실행되었지만, Linux 환경에서 g++로 컴파일을 한 경우에는 컴파일 에러가 발생하였습니다. 구글링을 통해 스택오버플로우 등 여기저기 찾아보았지만 해당 테스트 케이스와 같은 예가 없어서 여기에 질문을 올리게 되었습니다. 아래는 소스코드의 에러부분을 발췌하여 새로 만든 코드입니다.

#include <iostream>
using namespace std;

class Complex{
private:
    int real;
    int imag;

public:
    //constructor
    Complex(int r = 0, int i = 0) : real(r), imag(i) {}
    Complex(const Complex& copy) : real(copy.real), imag(copy.imag) {}

    //accessor
    int getReal()const { return real; }
    int getImag()const { return imag; }

    //global
    friend Complex operator*(int value, Complex& num);  

    //overloaded binary operator
    Complex operator*(const Complex& num)const;
    Complex operator*(const int value)const;

    //overload assignment operator
    Complex& operator=(const Complex& num);
    Complex& operator=(const int value);

    //overloaded unary operators
    Complex& operator++();
    Complex operator++(int);
    Complex& operator--();
    Complex operator--(int);
};

//global
Complex operator*(int value, Complex& num){
    return  num*value;
}

//overloaded binary operator
Complex Complex::operator*(const Complex& num)const{
    int newReal = (this->real)*num.getReal() - (this->imag)*num.getImag();
    int newImag = (this->real)*num.getImag() + (this->imag)*num.getReal();
    return Complex(newReal, newImag);
}
Complex Complex::operator*(const int value)const{
    int newReal = (this->real)*value;
    int newImag = (this->imag)*value;
    return Complex(newReal, newImag);
}

//overload assignment operator
Complex& Complex::operator=(const Complex& num){
    this->real = num.getReal();
    this->imag = num.getImag();
    return *this;
}
Complex& Complex::operator=(const int value){
    this->real = value;
    this->imag = 0;
    return *this;
}

//overloaded unary operators
Complex& Complex::operator++(){
    real += 1;
    return *this;
}
Complex Complex::operator++(int){
    Complex temp(*this);
    real += 1;
    return temp;
}
Complex& Complex::operator--(){
    real -= 1;
    return *this;
}
Complex Complex::operator--(int){
    Complex temp(*this);
    real -= 1;
    return temp;
}

//main
int main(){
    Complex c0, c1(1);

    c0 = (++c1) * 3; //Case_1
    c0 = 3 * (++c1); //Case_2
    c0 = (c1++) * 2; //Case_3
    c0 = 3 * (c1++); //Case_4 => Error
    return 0;
}

위의 Main에서 Case_1~3은 정상적으로 컴파일이 되지만 Case_4는 다음과 같은 Error 메시지를 출력합니다.

이미지

왜 g++에서는 Case_4번 에서 에러가 발생하는 것인지 너무나도 궁금합니다. 긴 글 읽어주셔서 감사합니다 (_ _)

  • 2016년 05월 20일에 작성됨

조회수 175


1 답변


좋아요
1
싫어요
채택취소하기

전역함수로 오버로딩한 부분에서 두번째 인자를 const를 써주세요. vs는 이걸 넘져주기 때문에 compile이 된다고 하네요. 연산자 오버로딩인 경우 r-value 중 객체는 const를 지정해주지 않으면 이런 에러가 발생하더라구요. 다음과 같이 수정한 뒤에 컴파일 해보세요~

    //global
    friend Complex operator*(int value, Complex const& num);  

    ...

    //global
    Complex operator*(int value, Complex const& num){
        return  num*value;
    }

아래는 전체 코드입니다.

#include <iostream>
using namespace std;

class Complex{
private:
    int real;
    int imag;

public:
    //constructor
    Complex(int r = 0, int i = 0) : real(r), imag(i) {}
    Complex(const Complex& copy) : real(copy.real), imag(copy.imag) {}

    //accessor
    int getReal()const { return real; }
    int getImag()const { return imag; }

    //global
    friend Complex operator*(int value, Complex const& num);  

    //overloaded binary operator
    Complex operator*(const Complex& num)const;
    Complex operator*(const int value)const;

    //overload assignment operator
    Complex& operator=(const Complex& num);
    Complex& operator=(const int value);

    //overloaded unary operators
    Complex& operator++();
    Complex operator++(int);
    Complex& operator--();
    Complex operator--(int);
};

//global
Complex operator*(int value, Complex const& num){
    return  num*value;
}

//overloaded binary operator
Complex Complex::operator*(const Complex& num)const{
    int newReal = (this->real)*num.getReal() - (this->imag)*num.getImag();
    int newImag = (this->real)*num.getImag() + (this->imag)*num.getReal();
    return Complex(newReal, newImag);
}
Complex Complex::operator*(const int value)const{
    int newReal = (this->real)*value;
    int newImag = (this->imag)*value;
    return Complex(newReal, newImag);
}

//overload assignment operator
Complex& Complex::operator=(const Complex& num){
    this->real = num.getReal();
    this->imag = num.getImag();
    return *this;
}
Complex& Complex::operator=(const int value){
    this->real = value;
    this->imag = 0;
    return *this;
}

//overloaded unary operators
Complex& Complex::operator++(){
    real += 1;
    return *this;
}
Complex Complex::operator++(int){
    Complex temp(*this);
    real += 1;
    return temp;
}
Complex& Complex::operator--(){
    real -= 1;
    return *this;
}
Complex Complex::operator--(int){
    Complex temp(*this);
    real -= 1;
    return temp;
}

//main
int main(){
    Complex c0, c1(1);

    c0 = (++c1) * 3; //Case_1
    c0 = 3 * (++c1); //Case_2
    c0 = (c1++) * 2; //Case_3
    c0 = 3 * (c1++); //Case_4 => Error
    return 0;
}

  • 2016년 05월 23일에 작성됨
    프론트앤드, 임베디드 초보개발자입니다

  • 덕분에 하나 더 배워갑니다. 친절한 답변 고맙습니다!(_ _)    WASHI   2016.5.23 10:40     
  • 저도 덕분에 오랜만에 c++ 복습했습니다! 열공합시다 ㅎㅎ    한인규   2016.5.23 10:43     

로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close