내가 알고싶은 것은 다형성이다. 다형성이란 다양한 형태를 가지는 것을 말한다. 여기서는 함수의 다양성을 말한다. 다형성은 코드의 재사용을 위해서 필요하다. 같은 함수라도 다양한 형태를 가진다는 것이다. 함수 오버로딩이랑 비슷한데 무슨 차이인지는 잘 모르겠다.
(ㅋㅋㅋㅋ 바보 같은 질문이었다. 오버로딩이 다형성의 대표적인 예시라고 한다.)
교재에 나와 있는 다형성의 예제를 하나 보자.
Complex n1, n2;
double d1, d2;
cout << n1 + n2 << endl;
cout << d1 + d2 << endl;
cout << d1 + n2 << endl;
Operator+ (Complex param1, Complex param2);
Operator+ (double p1, double p2);
Operator+ (double p1, Complex p2);
이것도 다형성의 개념이다. 같아 보이지만 다른 함수가 호출된다.
다형성의 개념은 클래스의 상속에서도 사용된다.
하지만 이 개념을 이해하기 전에 가상 함수에 대해 이해해야한다.
가상함수를 만드는 방법은 정말 간단하다.
class Person{
public:
virtual void speak(){
cout << "person class speak function \n";
}
};
이런 식으로 virtual 이라는 키워드만 작성해 주면 된다. 이것을 왜 쓰냐고 묻는다면 이것을 안 썼을 때 문제가 생기기 때문이다. c++에서 함수를 메모리에 담아둔다.
Student s1;
Professor p1;
Person* arr[2];
arr[0] = &s1;
arr[1] = &p1;
for (int i=0; i<2; i++)
arr[i] -> speak;
이런 식으로 포인터 클래스를 만들어주면 arr에는 Person에 대한 함수가 저장되어 버린다. 덮어쓰기가 안되는 것이다. 하지만 virtual로 하면 그 문제를 해결할 수 있는 것이다.
참고로 한번 virtual이라고 선언된 함수는 이후에도 자동적으로 virtual이 된다고 한다.
이런식으로 virtual을 쓰면 상속받은 클래스에서도 다형성을 유지할 수 있다. 같지만 다른 함수다. virtual인 상태로 위의 코드를 실행하면 다음과 같이 다른 결과가 나온다.
virtual을 썼을 때 컴파일러 입장에서 어떨까?
"프로그램에서 사용될 때까지 기다려야지! 나중에 또 나올 것이니까!" 이런 느낌일 것이다.
원래대로라면 메모리에 함수를 담아두어야 하지만 나중에 담겠다는 의미이다.
컴퓨터 구조에 대해 수업을 들었다면 좀 더 자세하게 이해했을 테지만 조금 아쉽다.
조금만 더 설명을 해보자... 이것은 동적인 바인딩과 연관이 있다고 한다. 동적인 바인딩은 파이썬에서 잘 쓰는 구조이다. 런타임에 따라 그 값이 변경되는 것이다.
진짜 가상함수라는 느낌이 팍팍 나는 개념이다. 딱히 함수 내용이 없지만 일단 메모리에 넣어두는 것이다.
virtual void darw() = 0;
이런식으로 가상 함수 = 0 으로 사용한다. 이런 순수 가상 함수를 가지는 클래스를 추상 클래스라고 한다.