본문 바로가기

C언어/기초

[C++] 함수 재정의와 오버라이딩란 무엇인가?

먼저 많은 글들을 살펴본 결과 C++는 오버라이딩에 대한 잘못된 설명이 인터넷에 돌아다니는 듯합니다.

그래서 제가 한방에 정리를 할 예정입니다.

먼저 기본적으로 이 정리 내용을 보기 전에 업캐스팅의 개념에 대해서는 잡혀있어야 됩니다.

먼저 함수 재정의부터 살펴보겠습니다.

함수 재정의

함수 재정의란 파생 클래스에서 기본 클래스와 동일한 형식의 함수를 작성하는 것입니다.

*여기서 동일한 형식이란 리턴 타입, 함수 이름, 매개 변수 타입 및 개수 등 전부 동일한 형식을 의미합니다.

이렇게 재정의된 함수는 기본 클래스의 포인터로 접근 시 기본 클래스의 함수가 호출되고,

파생 클래스의 포인터로 접근시 파생클래스의 함수가 호출됩니다.

즉, 이미 호출할 함수는 해당 포인터의 형태의 클래스에서 부르기 때문에 컴파일 시점에 결정되고 이것을 정적 바인딩이라 부릅니다.

뭐.. 중요한 건 부르는 포인터의 클래스에서 그대로 함수를 호출한다는 것입니다.

이해가 쉽도록 사진 설명도 하고 넘어갈게요.

자 이렇게 재정의된 함수가 존재할 때 사진의 f()를 호출할 때 각각 무엇을 호출할까요?

ap->f()도 c를 업캐스팅 하고 있지만 결국 포인터는 기본 클래스 A의 포인터이므로 A의 f()를 호출합니다.

그리고 b와 c 객체도 각각 b, c 내의 f()를 호출합니다.

 

그러면 오버라이딩은 무슨 차이가 있을까요?

함수 오버라이딩

함수 재정의와 클래스 내의 코드 자체는 거의 동일한데 대신 오버라이딩은 기본 클래스 함수 앞에 virtual 이 붙는다는 다른 점이 있습니다. virtual이 붙으면 바인딩을 동적으로 하는데 이게 무슨 소리냐.

방금 전의 사진을 다시 예를 들어 설명해보겠습니다.

함수 재정의와의 차이점을 살펴보면 오버라이딩 대상 기본 클래스의 함수 앞에 virtual이라는 키워드가 붙어있습니다.

이게 동적으로 바인딩을 하겠다는 의미인데 

ap->f()를 호출할 때 함수 재정의와의 차이점이 드러납니다.

ap->f()가 함수 재정의에서는 ap의 f() 함수를 호출하였는데 오버라이딩의 경우에는 ap는 파생 클래스 c를 업캐스팅 하고 있고 이러한 상황에서 ap로 f()를 호출하면 ap의 f()를 호출하기 전에 파생클래스에 오버라이딩이 되어있는 f()가 있나 없나 먼저 확인하고 존재하면 해당 함수를 호출하게 됩니다.

즉, 이 상황에서 ap파생 클래스인 c부터 f()가 있나 없나 체크를 하는데 존재하기 때문에 c의 f()를 호출하게 됩니다.

만약 c에는 없고 b에 있다면 b의 f()를 호출합니다.

전제조건은 A가 업캐스팅이 되어있어야 파생 클래스를 체크하겠죠? 그냥 기본 클래스의 객체만 생성된다면 파생 클래스는 딸려오지 않습니다.

 

이상으로 함수 재정의와 업캐스팅에 대해 설명드렸는데

부족한 부분이나 궁금한 부분이 있다면 꼭 댓글 남겨주세요!