(리턴 타입) operator(연산자) (연산자가 받는 인자)
bool operator==(myString& str);
bool myString::operator==(myString& s)
{
// myString에서 만든 함수로 s와 같으면 0을 리턴함
// 같을 때 true가 필요하므로 !를 써서 값을 뒤집음
return !compare(s);
}
기존에 만든 myString에 위 함수를 만든 후 아래와 같이 main 함수 실행
int main()
{
myString str1("a word");
myString str2("sentence");
myString str3("sentence");
if (str1 == str2)
std::cout << "str1 와 str2 같다." << std::endl;
else
std::cout << "st1 와 str2 는 다르다." << std::endl;
if (str2 == str3)
std::cout << "str2 와 str3 는 같다." << std::endl;
else
std::cout << "st2 와 str3 는 다르다" << std::endl;
}
실행 결과
st1 와 str2 는 다르다.
str2 와 str3 는 같다.
#include <iostream>
class Complex
{
private:
double real, img;
public:
Complex(double real, double img) : real(real), img(img) {}
Complex(const Complex& c) { real = c.real, img = c.img; }
Complex operator+(const Complex& c) const;
Complex operator-(const Complex& c) const;
Complex operator*(const Complex& c) const;
Complex operator/(const Complex& c) const;
void println() { std::cout << "( " << real << " , " << img << " ) " << std::endl; }
};
Complex Complex::operator+(const Complex& c) const
{
Complex temp(real + c.real, img + c.img);
return temp;
}
Complex Complex::operator-(const Complex& c) const
{
Complex temp(real - c.real, img - c.img);
return temp;
}
Complex Complex::operator*(const Complex& c) const
{
Complex temp(real * c.real - img * c.img, real * c.img + img * c.real);
return temp;
}
Complex Complex::operator/(const Complex& c) const
{
Complex temp(
(real * c.real + img * c.img) / (c.real * c.real + c.img * c.img),
(img * c.real - real * c.img) / (c.real * c.real + c.img * c.img));
return temp;
}
int main()
{
Complex a(1.0, 2.0);
Complex b(3.0, -2.0);
Complex c = a * b;
c.println();
}
실행 결과
( 7 , 4 )
// 연산자 함수 모두 Complex&가 아닌 Complex를 리턴해야 하는 이유
Complex& operator+(const Complex& c)
{
real += c.real;
img += c.img;
return *this;
}
Complex a = b + c + b;
// 사용자의 의도는 2 * b + c를 a에 대입하는 것이지만
// Complex&로 리턴하게 되면
// (b.plus(c)).plus(b) 중 b.plus(c)를 하면서 b에는 (b+c)가 들어가게 되고,
// 거기에 다시 plus(b)를 하게 되면 (b+c) + (b + c)가 됨
// 즉, 2 * b + 2 * c가 되어 사용자의 의도와 값이 달라지게 됨
// 대입 연수는 위의 사칙연산 함수와 다르게 자기 자신을 가리키는 &를 리턴해야 함
a = b = c;
// 위와 같은 코드에서 b = c;가 b를 리턴해야만 a = b;가 성공적으로 수행되기 때문
// 대입 연산 이후 불필요한 복사를 방지하기 위해 Complex& 타입으로 반환
Complex& Complex::operator=(const Complex& c)
{
real = c.real;
img = c.img;
return *this;
}
operator=를 만들지 않아도 잘 작동함
-> 컴파일러 차원에서 디폴트 대입 연산자를 지원하기 때문
디폴트 복사 생성자와 마찬가지로 디폴트 대입 연산자 역시 얕은 복사를 수행함
따라서, 깊은 복사가 필요한 클래스의 경우 대입 연산자 함수를 만들어주어야 함
(예) 클래스 내부에 동적 할당되는 메모리를 관리하는 포인터가 있는 경우
Complex& operator+=(const Complex& c);
Complex& operator-=(const Complex& c);
Complex& operator*=(const Complex& c);
Complex& operator/=(const Complex& c);
Complex& Complex::operator+=(const Complex& c)
{
(*this) = (*this) + c;
return *this;
}
Complex& Complex::operator-=(const Complex& c)
{
(*this) = (*this) - c;
return *this;
}
Complex& Complex::operator*=(const Complex& c)
{
(*this) = (*this) * c;
return *this;
}
Complex& Complex::operator/=(const Complex& c)
{
(*this) = (*this) / c;
return *this;
}
Some_Class a = b; // ①
Some_Class a; // ②
a = b;
① a의 '복사 생성자'가 호출
② a의 기본 생성자 호출 -> 대입 연산자 함수가 실행
Complex Complex::operator+(const char* str)
{
// 입력 받은 문자열을 분석하여 real 부분과 img 부분을 찾아야 한다.
// 문자열의 형태 : "[부호](실수부)(부호)i(허수부)"
// 이 때 맨 앞의 부호는 생략 가능 (생략시 + 라 가정)
int begin = 0, end = strlen(str);
double str_img = 0.0, str_real = 0.0;
// 먼저 가장 기준이 되는 'i' 의 위치를 찾는다.
int pos_i = -1;
for (int i = 0; i != end; i++)
{
if (str[i] == 'i')
{
pos_i = i;
break;
}
}
// 만일 'i' 가 없다면 이 수는 실수 뿐임
if (pos_i == -1)
{
str_real = get_number(str, begin, end - 1);
Complex temp(str_real, str_img);
return (*this) + temp;
}
// 만일 'i' 가 있다면, 실수부와 허수부를 나누어서 처리
str_real = get_number(str, begin, pos_i - 1);
str_img = get_number(str, pos_i + 1, end - 1);
if (pos_i >= 1 && str[pos_i - 1] == '-') str_img *= -1.0;
Complex temp(str_real, str_img);
return (*this) + temp;
}
double Complex::get_number(const char *str, int from, int to) const
{
bool minus = false;
if (from > to) return 0;
if (str[from] == '-') minus = true;
if (str[from] == '-' || str[from] == '+') from++;
double num = 0.0;
double decimal = 1.0;
bool integer_part = true;
for (int i = from; i <= to; i++)
{
if (isdigit(str[i]) && integer_part)
{
num *= 10.0;
num += (str[i] - '0');
}
else if (str[i] == '.')
integer_part = false;
else if (isdigit(str[i]) && !integer_part)
{
decimal /= 10.0;
num += ((str[i] - '0') * decimal);
}
else
break; // 그 이외의 이상한 문자들이 올 경우
}
if (minus) num *= -1.0;
return num;
}