'오버로딩 그리고 가상함수'에 해당되는 글 1건

  1. 2012.05.14 오버라이딩, 오버로딩 그리고 가상함수
98..Etc/Etc...2012. 5. 14. 19:36
반응형

 

 

 

author : LogerC

Date : 2009/12/28 22:35:59

 

 

왜...!!? 이 세가지를 구지 구분해야 할까요?

그냥 사용할줄 알면되지.. 구지 구분해서 알아둘 필요가 있을까요?

네.. 제가 드리고 싶은 말은!

구분해서 정확하게 알아두어야 합니다.

저도 3년 전만 해두... 왜 차이점에 대해서 물어보고, 트집잡는것인가 했었죠.

그러나... 이 차이점은 너무나 중요할뿐만 아니라, 이 세가지를 제대로 구분하지 않는다면

프로그래머로서의 한계가 오실꺼라 생각합니다. 코더에서 머무르시겠습니까?

더 높이 올라가시겠습니까?

 

 

오버라이딩 / 오버로딩 / 가상함수

정말 비슷해 보입니다. 차이점을 나열해 보라고 하면

참참참 난감하지요.

이 세가지를 제대로 분리해 낸다면 당신은 충분한 실력가 입니다.

중급의 입장에서 나누어 본 차이점 입니다.

 

고급으로 가실려면... 이 세가지의 차이점을 확실히 알고,

이 세가지 중에서 가상함수의 위대함을 이해 하고,

가상함수를 통한 OOP 설계가 가능 해집니다.

가상함수를 통한 OOP 설계가 가능해 질 쯔음,

오버라이딩과 오버로딩의 재미있는 것들도 함께 겸비 하시면.. 재미가 쏠쏠합니다. :)

 

일단... 초급을 떼기 위한 중급수준의 차이점을 나열해 보도록 하죠..

( 간혹 가다가.. 정말 짖궂게 이 세가지의 차이점을 묻는 윗분들이 계시지요..

근데.. 대부분 두가지의 차이점만 많이 물어봅니다. 오버라이딩/오버로딩... )

[ 설마.. 두가지만 물어본다는건.. 그 분은 가상함수를 모른다는거겠죠?

그분도 OOP를 절반밖에 모르는 군요.. 이런이런..아쉽군용..

당신이 거기에서 가상함수까지 쫘르르르 나열해 설명 해 준다면,

윗분께서~ 감탄사가 절로 나겠죠? ^^ ]

 

여기에는 차이점을 나열한 것이다. 각각의 정보에 대해 세밀한 정보를 원한다면.

Winapi사이트 같은 사이트를 둘러보기를 권한다.

또는 여러 지식인 검색 사이트를 사용하는 것도 현명한 방법이다.

 

오버라이딩#

덮어 씌운다.

 

  • 함수 오버라이딩

 [ 오버라이딩은 컴파일 시점에서 정해집니다. ]

 

상속관계에서 부모의 함수나 변수를 덮고, 새롭게 작성되어 쓰여진다.

over + ride 란 뜻은 위로 올라탄다는 의미입니다.

 

아래와 같이 간단한 예를 보자.

소스#

( compile 안한 코드임.. 이해를돕기 위한 코드)

  1. class parent {
  2. void foo() { printf("p"); }
  3. }
  4. class child : parent {
  5. void foo() { printf("c"); }
  6. }
  7.  
  8. main ()
  9. {
  10. child c;
  11. parent p;
  12.  
  13. c->foo();
  14. p->foo();
  15. }
출력#
  1. c
  2. p

 

 

 

오버로딩#

겹쳐  놓고 사용한다. ( 덮는게 아니라 겹친다. 다양한 사용이 가능하다 )

 

  • 함수오버로딩
  • 연산자오버로딩

 [ 오버로딩은 컴파일 시점에서 정해집니다. ]

 

over + load 란 더 많이 쌓는다는 거죠.

 

저 두가지의 공통점이 무엇인가? 잘모르겠지요...?

반환형 또는 매개변수로 오는 것이 달라집니다.

반환형(return), 매개변수( func(var) ) 에 따라 달라진다는 겁니다.

이제 조금 감이 올려나? ^^ ( 긴가민가 하실겁니다... 둘다 그랬었나? 이런생각하고계시나요? ㅎ )

 

함수 오버로딩이란

int foo(int, int);

double foo(double, int)

와 같이 같은 함수명에 매개변수 또는 반환형에 따라 재정의 되어 달라지는거죠

 

연산자 오버로딩이란

int operator+(int);

double operato+(const double);

과 같이 이미 정의된 연산자를 반환형이나 매개변수에 따라 재정의 되는 것이죠.

 

왜 오버로딩이라고 하는지 이해 하셨나요?

 

간단한 소스 적어보죠.

 

소스#

( compile 안한 코드임.. 이해를돕기 위한 코드)

  1. class Riding {
  2. private :
  3. double num;
  4. public:
  5. Riding() : num(0.0) { }
  6. double sum(const int a, const int b) { return (double)a+b; }
  7. double sum(const double a, const double b) { return a+b; }
  8.  
  9. double operator+(const int rhs) { return this.num += (double)rhs; }
  10. double operator+(const double rhs) { retrn this.num += rhs; }
  11. double operator=() { return num; }
  12. }
  13. int main(void) {
  14. Riding r;
  15.  
  16. cout << "int, int->" << r.foo(1,2) << " double, double->" << r.foo(1.0 + 3.0) << endl;
  17. cout << "int->" << r+1 << " double->" << r+2.0 << endl;
출력#
  1.  int, int-> 3.0 double,double->4.0
  2. int->1.0 double-> 3.0;

 

 

 

가상함수#

 

함수가 재정의 되어 사용합니다.

 

  • 겉에서 볼 때의 특성은 오버라이딩과 매우 흡사합니다.
  • 즉, 덮어 씌어진것처럼 보입니다.
  • 실제로는 오버로딩 되어, 겹쳐진 상태입니다.

    • 그러나 변환형, 매개변수가 달라지면 가상함수가 아닙니다.

[ 가상함수는 실행시간에 정해집니다. ]

 

너무 복잡하죠? 한마디로 한번 더 정리해 드리겠습니다.

  • 성법은 라이딩과 같은 모양새로 작성되지만, 실행과는 오버로딩처럼 보여집니다.

 

처음 접하신 분이라면, 이 내용을 이해 하기에는 큰 어려움이 있을꺼라 생각됩니다.

이상하게 생각하지 마십시오. 이걸 한번 보고 이해했다면, 당신은 프랑켄슈타인입니다.

 

가상함수는 상속관계에서 쓰여지며, 객체지향특성의 핵심중 핵심이라 할수 있습니다.

( 그래서 매우 어려운 것이죠 ... ) .. C에서는 포인터가 핵심이죠? C++이상의 객체지향에서는 가상함수가 핵심이라 해도 과언이 아닙니다.

 

이해를 돕기 위해 C 이야기 잠깐해보죠.

사용하셨었던 포인터 함수를 기억하시나요?

포인터 함수를 이용해서 가상함수를 흉내낼수도 있답니다.

리눅스같은 씨 구조로 된 OS에서 인터페이스로 포인터 함수를 가지고, 간결화시키죠.

객체지향에서는 가상함수를 가지고 인터페이스화 ( 간결하게 ) 시켜서, 거대한 프로젝트를 단순화 시켜줍니다.

( 가상함수 말고도, 다형성(추상화)을 이용해서 단순화를 시키기도 합니다. 이 내용은 주제에 벗어나므로 생략합니다. )

 

이제 다시 주제로 넘어오도록 하죠 ^^..

 

이 부분은 좀 어려우므로 소스를 보면서 이해 하도록하죠.

물론.. 이 소스도 컴파일 시도하지 않은, 이해를 돕기 위한 코드입니다.

 

소스#

( compile 안한 코드임.. 이해를돕기 위한 코드)

  1. class IMove {
  2. int go() = 0;
  3. }
  4. class Walk : IMove
  5. int go() { cout << " 저벅 저벅 " << endl; }
  6. }
  7. class Run : IMove
  8. int go() { cout << " 후다닥 후다닥 " << endl; }
  9. }
  10.  
  11. int main(void)
  12. {
  13. int    oops = 0;
  14. IMove* what_Do_I = NULL;
  15.  
  16. cout << " 걸을거면 1. 뛸꺼면 2.    고르세요! " << endl;
  17. cin >> oops;
  18.  
  19. switch(oops)
  20. {
  21. default:
  22. cout << "똑바로 안 누를래? .. 형이 지금 기분이 쫌 그런다.."
  23. break;
  24. case 1:
  25. what_Do_I = new Walk();
  26. break;
  27. case 2:
  28. what_Do_I = new Run();
  29. break;
  30. }
  31. if( NULL != what_Do_I )
  32. {
  33. what_Do_I.go();
  34. delete what_Do_I;
  35. }
  36.  
  37. return 0;
  38. }
  39.  

 

출력#

( 둘중 하나가 나온다. )

이게 바로.... 실행시간에 결정된다는 것이다.

  1. 저벅 저벅
  2. or
  3. 후다닥 후다닥

 

 

 

가상함수가 먼지 이제 이해 하셧나요?

가상함수는 정말 위대한 것입니다.

현재 당신이 이해 한 내용보다 훨씬 많은 내용을 담고 있습니다.

이제야 수학공부중.. 산수에 속하는.. 1,2,3,4,5,6,7,8,9를 떼셨습니다.

차 후에 좀 더 포스팅 하도록 하죠.

산수에 빗대어서 [ 0 ] 이라는 숫자를 발견했을 때는 어마어마한 발견이었죠.

가상함수를 통해서.. 그 어마어마한 발견을 하실 준비가 되신겁니다.



출처 : http://swstudy.springnote.com/pages/4902047

Posted by 1010