virtual
키워드가 붙은 맴버함수는 기반 클래스에서 선언되서, 파생클래스에 의해 재정의된다.
이러한 virtual
키워드를 사용하면 실행시간중에 다형성을 구현할 수 있다.
public
접근지정자여야 한다.ststic
일수 없다.base *p_base = &derived;
#include <iostream>
class base {
public :
virtual void base_func() {
std::cout << "base" << std::endl;
}
};
class derived : public base {
public :
void base_func() {
std::cout << "derived" << std::endl;
}
};
int main() {
base bs;
derived dr;
bs.base_func();
dr.base_func();
base *p_bs1 = &bs;
base *p_bs2 = &dr;
std::cout << "base포인터에 base의 주소\n> ";
p_bs1->base_func(); //> base
std::cout << "base포인터에 derived의 주소\n> ";
p_bs2->base_func(); //> derived
}
-> 런타임에 base_func()가 기반 클래스의 로직을 실행할지, 파생클래스의 로직을 실행할지 정해진다.
위처럼 파생 클래스에서 메소드를 잘 사용하면 문제가 안되지만, 미묘한 차이로 잘못사용해서 override되지 않고, 파생클래스의 새로운 맴버함수로서 만들어지는 경우가 있다.
ex) derived의 func1은 상수함수라서 override로 취급되지 않는다.
class Base {
...
public :
virtual void func1(int a) {
...
}
};
...
class derived : public Base {
...
public :
virtual void func1(int a) const {
...
}
};
이때, 파생클래스의 func1에 override
키워드를 붙여주면, override하는 func1이 아니면 컴파일 에러가 발생한다.
#include <iostream>
class Base {
public :
virtual void func1(int a) {
std::cout << a << std::endl;
}
};
class derived : public Base {
public :
//void func1(int a) const override {
//> 'override'로 선언된 멤버 함수는 기본 클래스 멤버를 재정의하지 않습니다.C/C++(1455)
void func1(int a) override {
std::cout << a + 42 << std::endl;
}
};
int main() {
derived dr;
Base *p_bs = &dr;
dr.func1(3); // 45
p_bs->func1(3); // 45 -> 기반클래스의 포인터지만, override됨.
}
override
키워드는 vertual
키워드와 꼭 같이쓸 필요는 없다. 그냥 override해야하는 맴버함수에 넣어주면 된다.