이번에는 연산자 오버로딩에 대해서 아래의 샘플코드를 통해서 알아보자.
#include <iostream>
class Complex
{
private:
double real, img;
double get_number(const char *str, int from, int to) const;
// 함수에 const 를 사용하면 해당 함수내부에서는 멤버 변수값을 변경못함.
public:
Complex(double real, double img) : real(real), img(img) {}
Complex(const Complex &c) { real = c.real, img = c.img; }
Complex(const char *str);
// a@b 는 a.operator@(b) 또는 operator@(a,b) 로 해석이 가능하다.
// 첫번째만 정의한 경우, a.operator@(b)만 정의할 경우는 const 키워드 유무와 상관없이 정상
// 둘다 정의한 경우, 2개의 함수중 어떤것을 콜해야하는지 몰라서 오류발생
// a+"1+i" 는 둘다 연산가능, "i+1"+a 는 두번째로만 연산가능
// operator+에서 const 키워드가 없어야 오류가 없음(operator@(a,b) 구현했기때문임).
Complex operator+(const Complex &c);
Complex operator-(const Complex &c) const;
Complex operator*(const Complex &c) const;
Complex operator/(const Complex &c) const;
// Complex operator+(const char *str) const;
// Complex operator-(const char *str) const;
// Complex operator*(const char *str) const;
// Complex operator/(const char *str) const;
Complex &operator=(const Complex &c);
void println() { std::cout << "( " << real << " , " << img << " ) " << std::endl; }
Complex &operator+=(const Complex &c);
Complex &operator-=(const Complex &c);
Complex &operator*=(const Complex &c);
Complex &operator/=(const Complex &c);
};
Complex::Complex(const char *str)
{
// 입력 받은 문자열을 분석하여 real 부분과 img 부분을 찾아야 한다.
// 문자열의 꼴은 다음과 같습니다 "[부호](실수부)(부호)i(허수부)"
// 이 때 맨 앞의 부호는 생략 가능합니다. (생략시 + 라 가정)
int begin = 0, end = strlen(str);
img = 0.0;
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)
{
real = get_number(str, begin, end - 1);
return;
}
// 만일 'i' 가 있다면, 실수부와 허수부를 나누어서 처리하면 된다.
real = get_number(str, begin, pos_i - 1);
img = get_number(str, pos_i + 1, end - 1);
// printf("str[%s], begin[%d], pos_i[%d], end[%d]\n", str, begin, pos_i, end);
if (pos_i == end - 1)
img = 1;
if (pos_i >= 1 && str[pos_i - 1] == '-')
img *= -1.0;
}
Complex Complex::operator+(const Complex &c)
{
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;
}
Complex &Complex::operator=(const Complex &c)
{
// TODO: insert return statement here
real = c.real;
img = c.img;
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;
}
Complex &Complex::operator/=(const Complex &c)
{
*this = *this / c;
return *this;
}
// Complex Complex::operator+(const char *str) const
// {
// Complex temp(str);
// return (*this) + temp;
// }
// Complex Complex::operator-(const char *str) const
// {
// Complex temp(str);
// return (*this) - temp;
// }
// Complex Complex::operator*(const char *str) const
// {
// Complex temp(str);
// return (*this) * temp;
// }
// Complex Complex::operator/(const char *str) const
// {
// Complex temp(str);
// 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;
}
Complex operator+(const Complex &a, const Complex &b)
{
Complex temp(a);
return temp.operator+(b);
}
int main()
{
// Complex a(1.0, 2.0);
// Complex b(3.0, -2.0);
// Complex c = a * b; // (7,4)
// Complex d = b + c + b; // ( 13 , 0 ), error ( 20 , 4 )
// c.println();
// d.println();
// Complex a(1.0, 2.0);
// Complex b(3.0, -2.0);
// Complex c(0.0, 0.0);
// c = a * b + a / b + a + b;
// c.println();
// b = a;
// c.println();
// Complex a(1.0, 2.0);
// Complex b(3.0, -2.0);
// a += b;
// a.println();
// b.println();
// Complex a(0, 0);
// // a = a + "-1.1 + i3.923";
// a = a + "-i";
// a.println();
Complex a(0, 0);
a = a + "-1.1 + i3.923";
a.println();
a = a - "1.2 -i1.823";
a.println();
a = a * "2.3+i22";
a.println();
a = a / "-12+i55";
a.println();
a = "-1.0 + i3.0" + a;
a.println();
a = "-1.0 + i3.0" + a;
a.println();
}
'C++' 카테고리의 다른 글
[C++] 상속(inheritance) - protected, private 키워드 (0) | 2023.02.16 |
---|---|
[C++] 상속(inheritance) (0) | 2023.02.16 |
[C++] 포인터 - 얕은복사/깊은복사(샘플3), 생성자, 소멸자 (0) | 2023.02.03 |
[C++] 포인터 - 얕은복사/깊은복사(샘플2) (0) | 2023.02.03 |
[C++] 포인터 - 얕은복사/깊은복사(샘플1) (0) | 2023.02.03 |