Operator Overloading
ex ) X = "Kim" + "Lee" 를 하고 X를 출력해서 KimLee 가 출력되게 하고싶은데 기본 C에서는 이게 불가능하다. 이때 C++에서 이를 가능하게 해주게 하기위해서 Operator Overloading 이다. |
[JAVA 에서는 사용 불가]
ex)복소수를 다룰 때 a = 3.1 + 5.4i b = 1.6 + 1.3i c = a + b; 이렇게 하나의 변수에 실수와 허수를 동시에 담아야 하니까 Class(구조체↑)를 사용하면 좋다. 이를 예시로 코드를 짜보겠다. 그저 완성된 마지막 코드를 원한다면 제일 밑을 보세요! |
먼저 복소수의 실수와 허수를 저장하기 위해
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class ComplexNumber { private : double m_x; // 실수부분 저장 double m_y; // 허수부분 저장 public : ComplexNumber(); }; ComplexNumber::ComplexNumber() { m_x = 0; // 처음에는 기본적으로 사용하지 않는경우에는 m_y = 0; // 0이라는 값이 입력이 되어있는게 좋음 } | cs |
이렇게 클래스를 하나 만들어서 실수와 허수를 저장할 변수를 지정해준다.
그 뒤
|
이렇게 함으로서 a와 b라는 복소수 2개를 만들어 줬다.
1 2 3 4 5 6 7 8 9 10 11 12 | class ComplexNumber { private : double m_x; // 실수부분 저장 double m_y; // 허수부분 저장 public : ComplexNumber(); void print() { cout << m_x << " + " << m_y << "i" << endl; } }; | cs |
그 뒤 복소수의 현재값을 출력해주는 함수를 만들어서 출력을 해보자.
1 2 3 4 5 6 7 | int main() { ComplexNumber a; ComplexNumber b; a.print(); b.print(); } | cs |
위와 같은 결과가 나오게된다. 처음 클래스 생성자에 m_x 와 m_y 에 0의 값을 넣을수 있게 해주었기 때문에
0+ 0i 라는 값이 2번 출력이 되게 된다. 여기서 값을 이제 입력시켜줄때
처음 생성할때부터 값이 입력이 되게해주면 얼마나 좋을까 해서
1 2 3 4 5 | ComplexNumber(double x, double y) { m_x = x; m_y = y; } | cs |
생성자를 하나 오버로딩 해주도록 한다.
(오버로딩 혹시나 모르면)
[Function Overloading][operator overloading][함수 오버로딩]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; class ComplexNumber { private : double m_x; // 실수부분 저장 double m_y; // 허수부분 저장 // 허수부분 저장 public : ComplexNumber(); ComplexNumber(double x, double y) { m_x = x; m_y = y; } void print() { cout << m_x << " + " << m_y << "i" << endl; } }; ComplexNumber::ComplexNumber() { m_x = 0; // 처음에는 기본적으로 사용하지 않는경우에는 m_y = 0; // 0이라는 값이 입력이 되어있는게 좋음 } int main() { ComplexNumber a(3.1,5.4); ComplexNumber b(1.6,1.3); a.print(); b.print(); } | cs |
그렇게해서 나오는 결과가 위에 코드이다.
여기서 우리가 원하는 것은 복소수 + 복소수 (a + b)의 결과로 복소수가 하나 나와서 c에 저장이 되는 결과이다.
나는 여기서 a에다가 b를 더하는 것을 c에 넣는다고 하여
1 2 3 4 5 6 7 8 9 | int main() { ComplexNumber a(3.1,5.4); ComplexNumber b(1.6,1.3); a.print(); b.print(); c = a.add(b); } | cs |
이런 식으로 사용을 하려한다. 그래서
반환형이 ComplexNumber 이며 함수이름 add 매개변수 b를 받을 ComplexNumber 형 타입의 매개변수 x 1개라는 함수를 만든다.
1 2 3 4 5 6 7 8 9 10 11 12 | ComplexNumber add(ComplexNumber x) { ComplexNumber tmp; // 창고로 쓸 ComplexNumber 형 변수 tmp.m_x = m_x + x.m_x; // tmp라는 창고변수에 a의 m_x와 매개변수로 //들어온 ComplexNumber 형의 m_x의 값을 더한것을 넣어준다 // 여기서 왜 m_x가 a의 것이냐면 // 현재 m_x 앞에는 this. 가 숨어있으며 현재 this가 가리키는 곳은 // add를 불러온 위치인 a이다. tmp.m_y = m_y + x.m_y; return tmp; } | cs |
그 결과코드로 아래와 같은 코드들이 생성이 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; class ComplexNumber { private : double m_x; // 실수부분 저장 double m_y; // 허수부분 저장 public : ComplexNumber(); ComplexNumber(double x, double y) { m_x = x; m_y = y; } void print() { cout << m_x << " + " << m_y << "i" << endl; } ComplexNumber add(ComplexNumber x) { ComplexNumber tmp; // 창고로 쓸 ComplexNumber 형 변수 tmp.m_x = m_x + x.m_x; // tmp라는 창고변수에 a의 m_x와 매개변수로 //들어온 ComplexNumber 형의 m_x의 값을 더한것을 넣어준다 // 여기서 왜 m_x가 a의 것이냐면 // 현재 m_x 앞에는 this. 가 숨어있으며 현재 this가 가리키는 곳은 // add를 불러온 위치인 a이다. tmp.m_y = m_y + x.m_y; return tmp; } }; ComplexNumber::ComplexNumber() { m_x = 0; // 처음에는 기본적으로 사용하지 않는경우에는 m_y = 0; // 0이라는 값이 입력이 되어있는게 좋음 } int main() { ComplexNumber a(3.1,5.4); ComplexNumber b(1.6,1.3); ComplexNumber c; a.print(); b.print(); c = a.add(b); c.print(); } | cs |
하지만 이런식으로 사용을 하게되면 문제가 많이 생긴다고한다.
또한 a와 b를 더하는건데 왜 tmp라는 변수와 x라는 입력받을 변수를 받을 변수를
또 만들어서 더해야하나? 라는 생각이 들수도있다.
평소 int형 a 와 b를 더하고 할때에는 그냥 a+b를 하면 되는데
굳이 tmp 를 만들 필요가 없다. 그래서 생각이 난게 &(Address Type)
1 2 3 4 5 6 7 8 9 10 11 12 | ComplexNumber add(ComplexNumber &x) {Address Type 을 사용해줌으로서 별명으로 처리를 해준다. ComplexNumber tmp; // 창고로 쓸 ComplexNumber 형 변수 tmp.m_x = m_x + x.m_x; // tmp라는 창고변수에 a의 m_x와 매개변수로 //들어온 ComplexNumber 형의 m_x의 값을 더한것을 넣어준다 // 여기서 왜 m_x가 a의 것이냐면 // 현재 m_x 앞에는 this. 가 숨어있으며 현재 this가 가리키는 곳은 // add를 불러온 위치인 a이다. tmp.m_y = m_y + x.m_y; return tmp; } | cs |
아까만든 add에서 Address Type을 사용하게 함으로서 x라는 이름은 사용을 하지만 b의 실제값 자체를 가져오게 되서
직접적인 b를 사용하게 된다.
Address Type 에 대해서는 나중에 한번 적어두겠습니다!
자 위처럼 하게 되어도.. ComplexNumber 타입의 tmp를 생성해서 만들게 되는데 이를 방지하기 위해서
1 2 3 4 | ComplexNumber add(ComplexNumber &x) { return ComplexNumber(m_x + x.m_x, m_y + x.m_y); } | cs |
이렇게 사용을 해줌으로서
ComplexNumber 형을 생성자로 만들어진후에 바로 return 을 함으로서 코드줄도 줄이고 쓸데없는 변수사용이 줄어들었다.
그런데 처음에 우리가 원하던것은
a.add(b) 이게 아닌
c= a+b 이다.
그래서 우리는
아래의 코드에서
1 2 3 4 5 6 7 8 9 10 11 | int main() { ComplexNumber a(3.1,5.4); ComplexNumber b(1.6,1.3); ComplexNumber c; a.print(); b.print(); c = a.add(b); c.print(); } | cs |
1 2 3 4 5 6 7 8 9 10 11 | int main() { ComplexNumber a(3.1,5.4); ComplexNumber b(1.6,1.3); ComplexNumber c; a.print(); b.print(); c = a.operator+(b); c.print(); } | cs |
add의 이름을 operator+ 로 바꾸어보자
이렇게 변경후
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | class ComplexNumber { private : double m_x; // 실수부분 저장 double m_y; // 허수부분 저장 public : ComplexNumber(); ComplexNumber(double x, double y) { m_x = x; m_y = y; } void print() { cout << m_x << " + " << m_y << "i" << endl; } ComplexNumber operator+(ComplexNumber &x) { return ComplexNumber(m_x + x.m_x, m_y + x.m_y); } }; | cs |
클래스 내부에서도 수정을 해보자.
그뒤 ! main 에서 operator+ 를 그냥 + 로 바꾸면
1 2 3 4 5 6 7 8 9 10 11 | int main() { ComplexNumber a(3.1,5.4); ComplexNumber b(1.6,1.3); ComplexNumber c; a.print(); b.print(); c = a + b; c.print(); } | cs |
이렇게 정상적인 결과가 나오게 된다!
언븰리버블!
이것을 응용하여 ! 음수도 만들어주면
1 2 3 4 | ComplexNumber operator-(ComplexNumber &x) { return ComplexNumber(m_x + x.m_x, m_y + x.m_y); } | cs |
이렇게 만들어 주며
실수값과 허수값을 가져오기 위해서는
1 2 3 4 5 6 | double real() { return m_x; } double imaginary() { return m_y; } | cs |
이렇게 구현하면 된다.
또한 복소수의 제곱근을 구하기 위해서는
1 2 3 4 | double magnitude() { return sqrt(m_x*m_x + m_y*m_y); } | cs |
또한 곱셈을 위해서는
1 2 3 4 5 6 7 8 | ComplexNumber operator*(ComplexNumber &x) { //곱셈은 실수*실수-허수*허수 ( i의 제곱은 -1이다 ) //this.실수 * 실수 - this.허수 * 허수 //실수 부분 //+ this.실수 * 허수i + 실수 * this.허수i //허수부분 double realPart = m_x * x.m_x - m_y*m_y ; double imaginaryPart = m_x*x.m_x + m_y*x.m_y; return ComplexNumber(realPart ,imaginaryPart); } | cs |
이렇게 만들어 주면 된다.
마지막 최종코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <math.h> using namespace std; class ComplexNumber { private ://생략하면 기본적으로 default 가 private 임. double m_x; // 실수부분 저장 double m_y; // 허수부분 저장 public : ComplexNumber(); ComplexNumber(double x, double y) { m_x = x; m_y = y; } void print() { //허수부분의 값이 -인경우 바꾸어줘야 하지만 // 그 정도는 할수있을거라 믿습니다! ㅎㅎㅎㅎ cout << m_x << " + " << m_y << "i" << endl; } double real() { return m_x; } double imaginary() { return m_y; } double magnitude() { return sqrt(m_x*m_x + m_y*m_y); } ComplexNumber operator+(ComplexNumber &x) { return ComplexNumber(m_x + x.m_x, m_y + x.m_y); } ComplexNumber operator-(ComplexNumber &x) { return ComplexNumber(m_x + x.m_x, m_y + x.m_y); } ComplexNumber operator*(ComplexNumber &x) { //곱셈은 실수*실수-허수*허수 ( i의 제곱은 -1이다 ) //this.실수 * 실수 - this.허수 * 허수 //실수 부분 //+ this.실수 * 허수i + 실수 * this.허수i //허수부분 return ComplexNumber(m_x * x.m_x - m_y*m_y ,m_x*x.m_x + m_y*x.m_y); } //ComplexNumber operator*(ComplexNumber &x) { // double realPart = m_x * x.m_x - m_y*m_y ; // double imaginaryPart = m_x*x.m_x + m_y*x.m_y; // return ComplexNumber(realPart ,imaginaryPart); //} }; ComplexNumber::ComplexNumber() { m_x = 0; // 처음에는 기본적으로 사용하지 않는경우에는 m_y = 0; // 0이라는 값이 입력이 되어있는게 좋음 } int main() { ComplexNumber a(3.1,5.4); ComplexNumber b(1.6,1.3); ComplexNumber c; a.print(); b.print(); //양수 계산 c = a + b; c.print(); //음수 계산 c = a - b; c.print(); //실수부분 추출 double r = a.real(); cout << "실수 출력 :: " << r << endl; double i = a.imaginary(); cout << "허수 출력 :: " << i << endl; ComplexNumber e; e = a * b; e.print(); } | cs |
'Dev > [C++]개념정리' 카테고리의 다른 글
[개탱][C++][shallow copy][deep copy] (0) | 2018.01.02 |
---|---|
[개탱][C++][Operator Overloading][Operator][Overloading][복소수][complexNumber][2] (0) | 2018.01.02 |
[개탱][C++][static][static data member][class][static function] (0) | 2018.01.02 |
[개탱][C++][template][Generic class] (0) | 2018.01.02 |
[개탱][C++][cin][cout][endl] (0) | 2018.01.02 |