주의! 함수 오버라이드가 c++에서 가능하지만 권장하지 않는 코딩이다. 그저 참조용으로만 알아둘 것.
함수 재정의가 필요한 경우에는 무조건 virtual 을 사용해야 한다.
함수 오버라이드 (function override)
- 기반 클래스가 가진 함수를 파생 클래스가 다시 만드는 것
- 주의! 오바라이딩과 오버로딩(overloading)은 다른 용어
#include <iostream>
class Shape
{
public:
void Draw() { std::cout << "Shape::Draw" << std::endl; }
};
class Rect : public Shape
{
public:
void Draw() { std::cout << "Rect::Draw" << std::endl; }
};
int main()
{
Shape s; s.Draw(); // Shape::Draw
Rect r; r.Draw(); // Rect::Draw
Shape* p = &r; //
p->Draw(); // Shape::Draw
}
기반 클래스 포인터로 파생 클래스를 가리킬 때 override된 함수를 호출하면
C++ 혹은 C#에서는 기반 클래스 함수를 호출한다.
(참고로, java, swift 언어에서는 파생 클래스 함수를 호출함.)
함수 바인딩 (binding)
p->Draw() 를 어느 함수와 연결 할 것인가?
방법 1. 컴파일 할 때 결정 하는 방법 - static binding
방법 2. 실행 할 때 결정 하는 방법 - dynamic binding
C++는 기본적으로 컴파일 할 때 함수 호출을 결정한다.
컴파일러는 컴파일 시간에 실제로 p가 어느 객체를 가리키는지 알 수 없다.
컴파일러가 컴파일 시간에 알고 있는 정보는 p는 Shape*라는 사실 밖에 없다.
Virtual function (가상 함수 )
어느 함수를 호출할지는 컴파일 시간에 하지 말고, 실행할 때 결정해 달라는 것.
메모리에 있는 객체를 조사한 후 호출함.
일반 멤버 함수와 가상 함수의 차이점
일반 멤버 함수 | static binding 컴파일러가 컴파일 시간 호출을 결정 포인터의 타입으로 함수 호출을 결정 Shape::Draw() 호출 |
가상 함수 (virtual function) | dynamic binding 실행 시간에 메모리를 조사해서 함수 호출을 결정 실제 메모리에 놓인 객체 타입으로 함수 호출 결정 Rect::Draw() 호출 |
Draw()를 virtual로 정의하면 실행 시간에 정의된 Rect 객체로 판단해서 Rect의 Draw()를 호출한다.
파생 클래스에 재정의 할거라면 virtual로 정의하는게 원칙!
#include <iostream>
class Shape
{
public:
virtual void Draw() { std::cout << "Shape::Draw" << std::endl; }
};
class Rect : public Shape
{
public:
virtual void Draw() { std::cout << "Rect::Draw" << std::endl; }
};
int main()
{
Shape s;
Rect r;
Shape* p = &r;
//--------------
//int n = 0;
//std::cin >> n;
//if ( n == 1 ) p = &s;
//--------------
// 아래 코드를 컴파일 할때
// p가 어느객체를 가리킬지 컴파일러가 알수 있을까 ?
p->Draw(); // Rect::Draw
}
C++ 에서 파생 클래스에서 재정의 할 함수에 대해서는 무조건 virtual을 쓰자!
가상 함수가 아닌 함수를 재정의 하지 말라.
C++의 격언이라고 하네요.
'C++' 카테고리의 다른 글
[C++] RTTI (Run Time Type Information) (0) | 2021.12.29 |
---|---|
[C++] 추상 클래스 (abstract class), 인터페이스(interface) (0) | 2021.12.28 |
[C++] upcasting (업캐스팅) (0) | 2021.08.27 |
[C++] 상속과 생성자 (파생 클래스 구현 방법 및 호출 순서) (0) | 2021.08.26 |
[C++] 상속 (Inheritance), protected (0) | 2021.08.25 |
댓글