up casting - 파생클래스의 인스턴스를 생성한 후, 기반 클래스의 포인터로 캐스팅하는 경우
#include <iostream>
#include <string>
class Base
{
std::string s;
public:
Base() : s("기반") { std::cout << "기반 클래스" << std::endl; }
void what() { std::cout << s << std::endl; }
};
class Derived : public Base
{
std::string s;
public:
Derived() : s("파생"), Base() { std::cout << "파생 클래스" << std::endl; }
void what() { std::cout << s << std::endl; }
};
int main()
{
Base p;
Derived c;
std::cout << "=== 포인터 버전 ===" << std::endl;
Base *p_base = &c;
p_base->what();
return 0;
}
업케스팅을 해서 파생 클래스이지만 기반 클래스의 정보를 찾을수 있다.
virtual 함수 - 기반 클래스 포인터를 이용하여 기반 클래스 인스턴스와 파생 클래스 인스턴스의 함수를 둘다 접근할 수 있게 만들어 주는 키워드. 예를 들면 포인터를 통해서 인스턴스들을 일괄 관리할때, 각각 관리하기 위해서 필요한 유사 코드(각각의 클래스 포인터 및 관련 함수들의 중복)들의 불필요한 중복을 피할수 있음.
#include <iostream>
class Base
{
public:
Base() { std::cout << "기반 클래스" << std::endl; }
virtual void what() { std::cout << "기반 클래스의 what()" << std::endl; }
};
class Derived : public Base
{
public:
Derived() : Base() { std::cout << "파생 클래스" << std::endl; }
void what() { std::cout << "파생 클래스의 what()" << std::endl; }
};
int main()
{
Base p;
Derived c;
Base *p_p[2];
p_p[0] = &p;
p_p[1] = &c;
std::cout << " == 실제 객체는 Base == " << std::endl;
p_p[0]->what();
std::cout << " == 실제 객체는 Derived == " << std::endl;
p_p[1]->what();
return 0;
}
위에서 배운 업캐스팅에 의하면 what 함수가 실행될때 무조건 기반 클래스의 what 함수가 실행되어야 하지만 virtual 키워드를 기반클래스의 what 함수에 적용하면 Base 포인터(*p_p)가 실행될때 내가 가리키는 인스턴스가 누구인지를 확인해서 기반 클래스의 함수를 호출할지 아니면 파생 클래스의 함수를 호출할지 결정됩니다.
이렇게 virtual 키워드를 사용하면 컴파일시에 어떤 함수가 실행될지 정해지지 않고 런타임 시에 정해지는 것을 동적 바인딩(dynamic binding)이라고 합니다.
참고자료 : 모두의 코드
'C++' 카테고리의 다른 글
[C++] 다중 상속(multiple inheritance) (0) | 2023.02.18 |
---|---|
[C++] 추상 클래스 (abstract class) (0) | 2023.02.18 |
[C++] 상속(inheritance) - protected, private 키워드 (0) | 2023.02.16 |
[C++] 상속(inheritance) (0) | 2023.02.16 |
[C++] 포인터 - 연산자 오버로딩(overloading) (0) | 2023.02.14 |