author : LogerC
Date : 2009/12/28 22:35:59
왜...!!? 이 세가지를 구지 구분해야 할까요?
그냥 사용할줄 알면되지.. 구지 구분해서 알아둘 필요가 있을까요?
네.. 제가 드리고 싶은 말은!
구분해서 정확하게 알아두어야 합니다.
저도 3년 전만 해두... 왜 차이점에 대해서 물어보고, 트집잡는것인가 했었죠.
그러나... 이 차이점은 너무나 중요할뿐만 아니라, 이 세가지를 제대로 구분하지 않는다면
프로그래머로서의 한계가 오실꺼라 생각합니다. 코더에서 머무르시겠습니까?
더 높이 올라가시겠습니까?
오버라이딩 / 오버로딩 / 가상함수
정말 비슷해 보입니다. 차이점을 나열해 보라고 하면
참참참 난감하지요.
이 세가지를 제대로 분리해 낸다면 당신은 충분한 실력가 입니다.
중급의 입장에서 나누어 본 차이점 입니다.
고급으로 가실려면... 이 세가지의 차이점을 확실히 알고,
이 세가지 중에서 가상함수의 위대함을 이해 하고,
가상함수를 통한 OOP 설계가 가능 해집니다.
가상함수를 통한 OOP 설계가 가능해 질 쯔음,
오버라이딩과 오버로딩의 재미있는 것들도 함께 겸비 하시면.. 재미가 쏠쏠합니다. :)
일단... 초급을 떼기 위한 중급수준의 차이점을 나열해 보도록 하죠..
( 간혹 가다가.. 정말 짖궂게 이 세가지의 차이점을 묻는 윗분들이 계시지요..
근데.. 대부분 두가지의 차이점만 많이 물어봅니다. 오버라이딩/오버로딩... )
[ 설마.. 두가지만 물어본다는건.. 그 분은 가상함수를 모른다는거겠죠?
그분도 OOP를 절반밖에 모르는 군요.. 이런이런..아쉽군용..
당신이 거기에서 가상함수까지 쫘르르르 나열해 설명 해 준다면,
윗분께서~ 감탄사가 절로 나겠죠? ^^ ]
여기에는 차이점을 나열한 것이다. 각각의 정보에 대해 세밀한 정보를 원한다면.
Winapi사이트 같은 사이트를 둘러보기를 권한다.
또는 여러 지식인 검색 사이트를 사용하는 것도 현명한 방법이다.
오버라이딩#
덮어 씌운다.
- 함수 오버라이딩
[ 오버라이딩은 컴파일 시점에서 정해집니다. ]
상속관계에서 부모의 함수나 변수를 덮고, 새롭게 작성되어 쓰여진다.
over + ride 란 뜻은 위로 올라탄다는 의미입니다.
아래와 같이 간단한 예를 보자.
소스#
( compile 안한 코드임.. 이해를돕기 위한 코드)
- class parent {
- void foo() { printf("p"); }
- }
- class child : parent {
- void foo() { printf("c"); }
- }
- main ()
- {
- child c;
- parent p;
- c->foo();
- p->foo();
- }
출력#
- c
- p
오버로딩#
겹쳐 놓고 사용한다. ( 덮는게 아니라 겹친다. 다양한 사용이 가능하다 )
- 함수오버로딩
- 연산자오버로딩
[ 오버로딩은 컴파일 시점에서 정해집니다. ]
over + load 란 더 많이 쌓는다는 거죠.
저 두가지의 공통점이 무엇인가? 잘모르겠지요...?
반환형 또는 매개변수로 오는 것이 달라집니다.
반환형(return), 매개변수( func(var) ) 에 따라 달라진다는 겁니다.
이제 조금 감이 올려나? ^^ ( 긴가민가 하실겁니다... 둘다 그랬었나? 이런생각하고계시나요? ㅎ )
함수 오버로딩이란
int foo(int, int);
double foo(double, int)
와 같이 같은 함수명에 매개변수 또는 반환형에 따라 재정의 되어 달라지는거죠
연산자 오버로딩이란
int operator+(int);
double operato+(const double);
과 같이 이미 정의된 연산자를 반환형이나 매개변수에 따라 재정의 되는 것이죠.
왜 오버로딩이라고 하는지 이해 하셨나요?
간단한 소스 적어보죠.
소스#
( compile 안한 코드임.. 이해를돕기 위한 코드)
- class Riding {
- private :
- double num;
- public:
- Riding() : num(0.0) { }
- double sum(const int a, const int b) { return (double)a+b; }
- double sum(const double a, const double b) { return a+b; }
- double operator+(const int rhs) { return this.num += (double)rhs; }
- double operator+(const double rhs) { retrn this.num += rhs; }
- double operator=() { return num; }
- }
- int main(void) {
- Riding r;
- cout << "int, int->" << r.foo(1,2) << " double, double->" << r.foo(1.0 + 3.0) << endl;
- cout << "int->" << r+1 << " double->" << r+2.0 << endl;
출력#
- int, int-> 3.0 double,double->4.0
- int->1.0 double-> 3.0;
가상함수#
함수가 재정의 되어 사용합니다.
- 겉에서 볼 때의 특성은 오버라이딩과 매우 흡사합니다.
- 즉, 덮어 씌어진것처럼 보입니다.
실제로는 오버로딩 되어, 겹쳐진 상태입니다.
- 그러나 변환형, 매개변수가 달라지면 가상함수가 아닙니다.
[ 가상함수는 실행시간에 정해집니다. ]
너무 복잡하죠? 한마디로 한번 더 정리해 드리겠습니다.
- 작성법은 오버라이딩과 같은 모양새로 작성되지만, 실행결과는 오버로딩처럼 보여집니다.
처음 접하신 분이라면, 이 내용을 이해 하기에는 큰 어려움이 있을꺼라 생각됩니다.
이상하게 생각하지 마십시오. 이걸 한번 보고 이해했다면, 당신은 프랑켄슈타인입니다.
가상함수는 상속관계에서 쓰여지며, 객체지향특성의 핵심중 핵심이라 할수 있습니다.
( 그래서 매우 어려운 것이죠 ... ) .. C에서는 포인터가 핵심이죠? C++이상의 객체지향에서는 가상함수가 핵심이라 해도 과언이 아닙니다.
이해를 돕기 위해 C 이야기 잠깐해보죠.
사용하셨었던 포인터 함수를 기억하시나요?
포인터 함수를 이용해서 가상함수를 흉내낼수도 있답니다.
리눅스같은 씨 구조로 된 OS에서 인터페이스로 포인터 함수를 가지고, 간결화시키죠.
객체지향에서는 가상함수를 가지고 인터페이스화 ( 간결하게 ) 시켜서, 거대한 프로젝트를 단순화 시켜줍니다.
( 가상함수 말고도, 다형성(추상화)을 이용해서 단순화를 시키기도 합니다. 이 내용은 주제에 벗어나므로 생략합니다. )
이제 다시 주제로 넘어오도록 하죠 ^^..
이 부분은 좀 어려우므로 소스를 보면서 이해 하도록하죠.
물론.. 이 소스도 컴파일 시도하지 않은, 이해를 돕기 위한 코드입니다.
소스#
( compile 안한 코드임.. 이해를돕기 위한 코드)
- class IMove {
- int go() = 0;
- }
- class Walk : IMove
- int go() { cout << " 저벅 저벅 " << endl; }
- }
- class Run : IMove
- int go() { cout << " 후다닥 후다닥 " << endl; }
- }
- int main(void)
- {
- int oops = 0;
- IMove* what_Do_I = NULL;
- cout << " 걸을거면 1. 뛸꺼면 2. 고르세요! " << endl;
- cin >> oops;
- switch(oops)
- {
- default:
- cout << "똑바로 안 누를래? .. 형이 지금 기분이 쫌 그런다.."
- break;
- case 1:
- what_Do_I = new Walk();
- break;
- case 2:
- what_Do_I = new Run();
- break;
- }
- if( NULL != what_Do_I )
- {
- what_Do_I.go();
- delete what_Do_I;
- }
- return 0;
- }
출력#
( 둘중 하나가 나온다. )
이게 바로.... 실행시간에 결정된다는 것이다.
- 저벅 저벅
- or
- 후다닥 후다닥
가상함수가 먼지 이제 이해 하셧나요?
가상함수는 정말 위대한 것입니다.
현재 당신이 이해 한 내용보다 훨씬 많은 내용을 담고 있습니다.
이제야 수학공부중.. 산수에 속하는.. 1,2,3,4,5,6,7,8,9를 떼셨습니다.
차 후에 좀 더 포스팅 하도록 하죠.
산수에 빗대어서 [ 0 ] 이라는 숫자를 발견했을 때는 어마어마한 발견이었죠.
가상함수를 통해서.. 그 어마어마한 발견을 하실 준비가 되신겁니다.