반응형
C++ Various overloading.
1.C++ Friend keyword
friend Complex operator+(const Complex& a, const Complex& b);
Complex operator+(const Complex& a, const Complex& b)
{
Complex temp(a.real + b.real, a.img + b.img);
return temp;
}
2.C++ I / O operator overloading
cout << a;라고 하는 것은 cout.operator<<(a) 를 하는 것과 동일한 명령이다. 즉, cout이라는 객체에 멤버 함수 operator<< 가 정의되어 있어서 a 를 호출하게 되는 것이다. 그런데, cout 이 int 나 double 변수, 심지어 문자열 까지 자유 자재로 operator<< 하나로 출력할 수 있던 이유는 그 많은 수의 operator<< 함수들이 오버로딩 되어 있다는 뜻이다.
Complex c;
cout << c;
===============
Complex c;
c.println();
3.C++ Subscript operator
배열에서 원소를 지정할 때 사용되는 첨자 연산자 [] 를 오버로딩 해보자.
cf) 첨자 연산자라고 부르냐면, 배열의 원소를 지정할 때 [] 안에 넣는 수를 첨자(subscript) 라고 부르기 때문이다. 클래스에서 개개의 문자에 접근하기 위해 [] 를 지원해주어야만 한다. [] 를 이용해서 str[10] 과 같이 10 번째 문자에 정확하게 접근할 수 있게 된다. 클래스의 operator[] 를 추가해보도록 해본다. operator[] 함수는 자명하게도 인자로 몇 번째 문자인지, int 형 변수를 인덱스로 받게 된다. 따라서 operator[] 는 아래와 같은 식을 가진다.
char& operator[] (const int index); //Q
str[10] = 'c'; //W
index 로 [] 안에 들어가는 값을 받게 된다. 그리고 char& 를 인자로 리턴하는 이유는 W같은 명령을 수행하기 때문에, 그 원소의 레퍼런스를 리턴하게 되는 것이다.실제로 opreator[] 의 구현은 아래와 같이 매우 단순하다.
char& MyString::operator[] (const int index)
{
return string_content[index];
}
위와 같이 index 번째의 string_content 를 리턴해서, operator[] 를 사용하는 사용자가, 레퍼런스를 가질 수 있게 된다.4.C++ Type conversion operator
int Wrapper class = > Wrapper 라는 것은 포장할 때 '랩(wrap)으로 싼다' 라고 하는 것처럼, '포장지' 라는 의미의 단어다. 즉 Wrapper 클래스는 무언가를 포장하는 클래스라는 의미인데, C++에서 프로그래밍을 할 때 어떤 경우에 기본 자료형들을 객체로써 다루어야 할 때가 있다. 이럴 때, 기본 자료형들 (int, float 등등) 을 클래스로 포장해서 각각의 자료형을 객체로 사용하는 것을 Wrapper 클래스를 이용한다는 뜻이다.
class Int
{
int data;
// 다른 데이터.
public:
Int(int data) : data(data) {}
Int(const Int& i) : data(i.data) {}
};
Int 클래스에 int 형 자료형을 보관하는 data 라는 변수를 정의해 놓았는데, 이렇게 한다면 int 형 데이터를 저장하는 객체로 Int 클래스를 사용할 수 있을 것이다.
operator (변환 하고자 하는 타입) ()
타입 변환 연산자는 위와 같다.
Wrapper 클래스의 객체를 마치 'int 형 변수' 라고 컴파일러가 생각할 수 있다. 왜냐하면 타입 변환 연산자가 있기 때문이다. 만일 컴파일러가 이 클래스의 객체를 int 형 변수로 변환할 수 있다면, 비록 operator+ 등을 정의하지 않더라도 컴파일러가 가장이 객체를 int 형 변수로 변환 한 다음에 + 를
수행할 수 있기 때문이다.
operator int()
{
return data;
}
단순히 data 를 리턴해주면 된다. 그렇게 된다면 Wrapper 클래스의 객체를 '읽는' 데에는 아무런 문제가 없게 된다.
왜냐하면 컴파일러 입장에서 적절한 변환 연산자로 operator int 를 찾아서 결국 int 로 변환해서 처리하기 때문이다.
다만 문제는 '대입' 시에 발생하는데, 다행이도 디폴트 대입 연산자가 이 역시 알아서 잘 처리할 것이기 때문에 상관없다.5.Potential / post-increment operator
a ++;
++ a;
흔히 생각하기에 ++ 연산자는 그냥 1 증가 시켜주는 1 개의 연산자라고 볼 수 있지만, 놀랍게도 C++ 에서는 ++ 연산자를 전위와 후위를 구분해서 오버로딩 할 수 있도록 제공하고 있다.
C++ 아래 소스로 구분한다.
operator++ ()=====x1
operator-- ()=====x2
==================
operator++ (int x)===y1
operator-- (int x)===y2
x1,x2와 같은 전위 증감 연산자 (++x, --x) 를 오버로딩 하게 된다.
y1,y2와 같은 후위 증감 연산자 (x++, x--)를 바로 구현한다.
물론 인자 x 에는 0 이 들어가게 된다.
즉 단순히 전위와 후위를 구별하기 위해 인자로 x 를 넣어주는 것이다.
실제로 ++ 을 구현하면서 인자로 들어가는 값을 사용하는 경우는 없다. 한 가지 주목할 점은 많은 경우 전위 증감이 후위 증감 보다 더 빠르기 때문에 (물론, 엄청나게 빠르다는 것이 아니라 후위 증감 자체가 약간의 연산을 더 수행하게 된다)
후위/전위 증감 중 무엇을 사용하던 상관이 없는 경우 (예를 들어서 for 문에서 i ++ 을 한 다던지) 되도록이면, 전위 증감을 사용하는 것이 바람직하고, 클래스를 사용하는 사용자의 입장에서는 두 개 모두 지원해야 한다.
6.C++ Conclusion for operators
1.두 개의 동등한 객체 사이에서의 이항 연산자는 멤버 함수가 아닌 외부 함수로 오버로딩 하는 것이 좋다.
Ex) Complex 의 operator+(const Complex&, const Complex&).
2.두 개의 객체 사이의 이항 연산자 이지만 한 객체만 값이 바뀐다던지 등의 동등하지 않는 이항 연산자는 멤버 함수로 오버로딩 하는 것이 좋다. Ex) operator+= 는 이항 연산자 이지만, operator+=(const Complex&) 가 낫다.
3.단항 연산자는 멤버 함수로 오버로딩 하는 것이 좋다. Ex) operator++ 의 경우 멤버 함수로 오버로딩.
4.일부 연산자들은 반드시 멤버 함수로만 오버로딩 해야 한다.
반응형
'#Programming Language > C++' 카테고리의 다른 글
C++ Standard String & Inheritance. (0) | 2018.04.01 |
---|---|
C++ Various overloading part 2. (0) | 2018.04.01 |
C++ Operator overloading. (0) | 2018.04.01 |
C++ Your Own String Class (0) | 2018.04.01 |
C++ Object-oriented programming. (0) | 2018.03.30 |