virtual 키워드로 선언된 멤버 함수로, 함수 호출을 실행 시간까지 미루도록 지시하여 동적 바인딩을 가능하게 함.virtual을 쓰지 않은 함수를 재정의한 경우, 컴파일 시간에 결정되어 단순히 호출되도록 정적 바인딩.
class Base {
public:
virtual void virtualFunc() { cout << "Base::virtualFunc() called" << endl; } // 가상 함수
void nonVirtualFunc() { cout << "Base::nonVirtualFunc() called" << endl; } // 비가상 함수
};
class Derived : public Base {
public:
void virtualFunc() override { cout << "Derived::virtualFunc() called" << endl; } // 가상 함수 오버라이딩
void nonVirtualFunc() { cout << "Derived::nonVirtualFunc() called" << endl; } // 함수 재정의
};
int main() {
Derived d;
Base* pBase = &d; // 업캐스팅
// 동적 바인딩: Derived 클래스의 가상 함수가 호출됨
pBase->virtualFunc(); // 출력: Derived::virtualFunc() called
// 정적 바인딩: Base 클래스의 비가상 함수가 호출됨
pBase->nonVirtualFunc(); // 출력: Base::nonVirtualFunc() called
return 0;
}


기본클래스::가상함수()형태로 기본 클래스의 가상 함수를 정적 바인딩으로 호출. 참고로, 정적 바인딩은 컴파일 시간에 결정되는 것이고, 동적 바인딩은 실행 시간에 결정되는 것이다.

virtual 키워드로 선언하여 동적 바인딩을 통해 파생 클래스의 소멸자가 호출되도록 함.
class Base {
public:
virtual ~Base() { cout << "~Base() called" << endl; }
};
class Derived : public Base {
public:
~Derived() { cout << "~Derived() called" << endl; }
};
int main() {
Base* p = new Derived();
delete p; // ~Derived() -> ~Base() 호출
}
class Shape {
public:
virtual void draw() = 0; // 순수 가상 함수
};
class Circle : public Shape {
public:
void draw() override { cout << "Circle" << endl; }
};
int main() {
Shape* p = new Circle();
p->draw(); // Circle 출력
delete p;
}
#include <iostream>
using namespace std;
class Base {
public:
void f() { cout << "Base::f() called" << endl; }
};
class Derived : public Base {
public:
void f() { cout << "Derived::f() called" << endl; }
};
int main() {
Derived d;
d.f(); // Derived::f() 호출
Base* pBase = &d; // 업캐스팅
pBase->f(); // Base::f() 호출
}
#include <iostream>
using namespace std;
class Base {
public:
virtual void f() { cout << "Base::f() called" << endl; }
};
class Derived : public Base {
public:
void f() override { cout << "Derived::f() called" << endl; }
};
int main() {
Derived d;
Base* pBase = &d; // 업캐스팅
pBase->f(); // Derived::f() 호출 (동적 바인딩)
}
#include <iostream>
using namespace std;
class Base {
public:
virtual void f() { cout << "Base::f() called" << endl; }
};
class Derived : public Base {
public:
void f() override { cout << "Derived::f() called" << endl; }
};
class GrandDerived : public Derived {
public:
void f() override { cout << "GrandDerived::f() called" << endl; }
};
int main() {
GrandDerived g;
Base* pBase = &g;
Derived* pDerived = &g;
GrandDerived* pGrand = &g;
pBase->f(); // GrandDerived::f() 호출 (동적 바인딩)
pDerived->f(); // GrandDerived::f() 호출 (동적 바인딩)
pGrand->f(); // GrandDerived::f() 호출
}
#include <iostream>
using namespace std;
class Shape {
public:
virtual void draw() { cout << "--Shape--" << endl; }
};
class Circle : public Shape {
public:
void draw() override {
Shape::draw(); // 기본 클래스의 draw() 호출
cout << "Circle" << endl;
}
};
int main() {
Circle circle;
Shape* pShape = &circle;
pShape->draw(); // --Shape--Circle 출력 (동적 바인딩)
pShape->Shape::draw(); // --Shape-- 출력 (정적 바인딩)
}
#include <iostream>
using namespace std;
class Base {
public:
virtual ~Base() { cout << "~Base()" << endl; }
};
class Derived : public Base {
public:
~Derived() { cout << "~Derived()" << endl; }
};
int main() {
Derived* dp = new Derived();
Base* bp = new Derived();
delete dp; // ~Derived() -> ~Base() 호출
delete bp; // ~Derived() -> ~Base() 호출
}
#include <iostream>
using namespace std;
class Calculator {
protected:
int a, b;
virtual int calc(int a, int b) = 0; // 순수 가상 함수
public:
void input() {
cout << "정수 2개를 입력하세요>> ";
cin >> a >> b;
}
void run() {
input();
cout << "계산된 값은 " << calc(a, b) << endl;
}
};
class Adder : public Calculator {
protected:
int calc(int a, int b) override {
return a + b;
}
};
class Subtractor : public Calculator {
protected:
int calc(int a, int b) override {
return a - b;
}
};
int main() {
Adder adder;
Subtractor subtractor;
adder.run(); // 덧셈 결과 출력
subtractor.run(); // 뺄셈 결과 출력
}