C++ Operator overloading.
1.Introduction
C++ 에서는 사용자 정의 연산자를 사용할 수 있다. 무슨 연산자들이 가능하냐면, :: (범위 지정), . (멤버 지정), .* (멤버 포인터로 멤버 지정) 을 제외한 모든 연산자를 사용할 수 있다. +, -, * 는 물론이고, +=, -= 와 같은 축약형들이나 >=, ==, 와 같은 비교 연산자, && 와 같은 논리 연산자, -> 와 같은 멤버 선택 연산자, ++, -- 증감 연산자, [] 와 심지어 () 까지 (함수 호출 연산자) 도 모두 직접 만들 수 있다.
(리턴 타입) operator(연산자) (연산자가 받는 인자)
cf)위 방법 외에는 함수 이름으로 연산자를 넣을 수 없다.== 를 오버로딩 하고 싶다면, == 연산자는 그 결과값이 언제나 bool 이고, 인자로는 == 로 비교하는 것 하나만 받게 된다.
따라서 다음과 같이 함수를 정의하면 된다.
bool operator== (MyString& str);
str1 == str2 라는 명령을 한다면, str1.operator==(str2) 로 내부적으로 변환되서 처리되고, 결과값을 리턴한다.operator== 를 만드는 것 자체는 어려운 일은 아니다. 왜냐하면 compare 라는 좋은 함수를 제공하고 있기 때문이다.
간단하게 만들어 보면 다음과 같습니다.
bool MyString::operator== (MyString& str)
{
return !compare(str); // str 과 같으면 compare 에서 0 을 리턴.
}
!compare(str) 을 리턴하는 이유는 compare 함수에서 str 과 *this 가 같으면 0 을 리턴하도록 하는데, operator== 은 둘이 같으면 true 를 리턴 해야된다. 따라서 NOT 연산자인 ! 를 앞에 붙여서 리턴하면 올바르게 작동할 수 있다.3.C++Complex number class
일단 실수의 제곱근에 대해서는 무엇인지 알 것이라 생각한다. 그런데 실수의 제곱은 언제나 양수이기 때문에 위와 같이 음수의 제곱근은 실수로 표현할 수 없게 된다. 즉, 음수의 제곱근을 나타내기 위해서 특별한 수를 정의하였는데 이를 허수(imaginary number) 이라 부르며, 실제로 존재하지 않는 수학적으로만 존재하는 수라고 볼 수 있다. 그리고 특히 -1 의 제곱근을 위의 수식 처럼 i 로 표기한다. 그리고 복소수는, 이 허수와 실수를 모두 포함하는 수 체계로, 허수와 실수의 합으로 표현할 수 있다.
만들고자 하는 것은 이 복소수를 나타내는 클래스를 구성하려고 한다. 임의의 복소수 하나를 표현하기 위해서 두 개의 값(실수부, 허수부)이 필요하기 때문에 반드시 클래스로 구현을 해야 한다. 따라서, 기본적으로 복소수 클래스 Complex 는 아래과 같이 만들 수 있다.
class Complex { private: double real, img; public: Complex(double real, double img) : real(real), img(img) {} };
복소수는 실수부와 허수부로 나뉘어지므로, Complex 클래스 역시 실수부의 값과 허수부의 값을 나타내는 real 과 img 변수가 있다.
문제는 사칙 연산이 자주 쓰인다는 것이다. 문자열의 덧셈 (+연산) 까지는 생각할 수 있다 해도, 곱셈이나 나눗셈 연산 자체는 고려할 필요가 없는데, 복소수의 경우 당연히 클래스 인터페이스 차원에서 곱셈과 나눗셈을 지원해주어야만 한다.
참고로, 복소수의 사칙 연산은 실수부와 허수부 따로 생각하여 진행된다.
곱셈의 경우는 좀 더 복잡한데, 사실 분배법칙과 허수 둘을 곱하면 다시 -1 이 된다는 점만 생각하면 된다.
나눗셈의 경우, 이전에 무리수의 유리화를 하던 것을 생각하면 간단한다.
즉 분모를 실수화 할 수 있도록 분모의 켤레를 분자와 분모에 곱함으로써 실수로 나누는 것으로 쉽게 바꿀 수 있다.
(실수로 나누는 것은 실수부,허수부의 실수값을 실수로 나누면 된다)
연산자의 오버로딩을 모른다고 가정하고 Complex 클래스를 구성하여 본다.
class Complex
{
private:
double real, img;
public:
Complex(double real, double img) : real(real), img(img) {}
Complex plus(const Complex& c);
Complex minus(const Complex& c);
Complex times(const Complex& c);
Complex divide(const Complex& c);
};
a + b/c + d;
a.plus(b.divide(c)).plus(d);
Complex& operator=(const Complex& c);
Complex& Complex::operator=(const Complex &c)
{
real = c.real; img = c.img;
return *this;
}
Some_Class a = b; //Q
Some_Class a; // W
a = b;
이제 두 문장의 차이를 알 수 있다.이전에 이야기 하였을 때 연산자 오버로딩을 배우지 못하였기 때문에 넘어갔지만 이제는 제대로 이해할 수 있다. Q의 경우, 아예 a 의 '복사 생성자' 가 호출되는 것이고, W의 경우 a 의 기본 생성자가 호출 된 다음, 다음 문장에서 대입 연산자 함수가 실행되는 것이다. 위 두 문장은 비록 비슷해 보이기는 해도 아예 다른 것이다.
5.C++ Complex numbers and additions as strings'#Programming Language > C++' 카테고리의 다른 글
C++ Various overloading part 2. (0) | 2018.04.01 |
---|---|
C++ Various overloading. (0) | 2018.04.01 |
C++ Your Own String Class (0) | 2018.04.01 |
C++ Object-oriented programming. (0) | 2018.03.30 |
C++ Everything in an object. (0) | 2018.03.30 |