Monday, September 27, 2010

C++ part 4 (객체지향의 완성)

이제 마지막 파트이다. 아마도 C++을 시작한지 2주쯤 되는거 같다. 확실히 oop를 다시 보는거라 처음 자바로 시작할때보다 기억이 오래가고 이해가 빠르다. 마지막 4장을 향해서 고고~! 


chapter10 : 연산자 오버로딩
연산자 오버로딩은 일종의 약속같은 것으로 기존의 연산자에 프로그래머가 추가적인 기능(새로운 피연산자등)을 확장시키는것. 예를 들어 p라는 객체가 있으면 p+3 과 같은 연산이 가능하게끔 연산자 +에 대해 새로히 연산자를 오버로딩하는 것이다.
연산자 오버로딩하는방법에 두가지가 있다. 한 코드의 예를 가지고 각각의 방법으로 연산자 오버로딩하는 것을 설명하겠다. main함수에 Point p1(1,2); Point p2(2,1); Point p3=p1+p2 라는 코드가 있다면... 
1.멤버 함수에 의한 오버로딩 : 클래스의 멤버 함수로 연산자를 오버로딩 하는 것으로 위를 위한 코드는 class Point{public:Point operator+(const Point& p){Point temp(x+p.x,y+p.y);return temp;}} 과 같이 연산자 오버로딩을 위한 함수를 클래스 Point 안에 명시한다. 위의 마지막 문장 Point p3=p1+p2는 Point p3=p1.operator+(p2) 으로 해석된다. 기억해야 할것은 main함수에 p3=p1+p2에서 p1.operator+(p2)가 호출되고 결과인 temp 객체가 리턴되서 default 복사 생성자에 의해 p3이 생성되는 것이다.
2.전역 함수에 의한 오버로딩 : 연산자 오버로딩을 위한 함수를 전역 함수로 명시하는 것으로 위의 경우 Point operator+(const Point& p1, const Point& p2){Point temp(p1.x+p2.x,p1.y+p2.y); return temp;} 식으로 전역 함수로 표현할수 있다. 단 객체의 멤버 변수를 직접 접근하므로 operator+를 friend로 지정해야 한다. 이때 main의 마지막 문장 Point p3=p1+p2는 Point p3=operator+(p1,p2)를 의미하게 된다.
필자에 따르면 객체지향에서는 전역이라는 개념이 없기 때문에 멤버 함수로의 연산자 오버로딩을 권한다.
단항 연산자 오버로딩은 위의 이항 연산자랑 매개변수가 하나씩 적다는것 빼고 동일하다. 기억해야 할것은 '++'를 오버로딩할때 이를 멤버 함수로 구현해보면 Point& operator++(){x++;y++;return *this;}이다. 여기서 return 이 존재 하여야 하고 그 type이 reference 이여야 한다. p라는 객체가 있을 때 (++(++p)).ShowPosition()을 고려해 보면 return이 없으면 ++한뒤의 돌아오는 결과물이 없게 되서 에러가 나고 type이 reference가 아니면 돌아오는 것이 객체의 copy가 돌아오기때문에 정작 p의 값은 2가 더해진 것이 아니라 1이 더해지게된다(++p는 p.operator++()로 p++는 p.operator++(int)로 구분된다). 
연산자 오버로딩을 통해 객체에 더하기가 가능할때, 즉 p+3, 교환법칙(3+p)가 가능하게 하기 위해서는 어쩔수 없이 전역 함수에 의한 오버로딩으로 구현해야 한다.
cout 은 ostream의 객체이고 cin은 istream의 객체이고 std라는 namespace에 존재하는 것이다. 그리고 <<나 >> 역시 연산자일 뿐이다. 그래서 cout<<"aa"라고 하는 것은 ostream클래스의 객체인 cout의 operator<<()를 호출하는 것이다.