가상함수
- 멤버 함수 가운데 자식 클래스에서 오버라이딩해야 하는 함수
virtual 반환_형식 함수_이름(매개변수)
virtual 반환_형식 함수_이름(매개변수) override;
- 업캐스팅 사용 시 부모클래스의 함수호출이 아닌 자식 클래스의 함수 호출을 함
바인딩
- 바인딩 : 함수 호출이나 변수 참조가 해당코드와 연결
정적바인딩
- 컴파일할때 결정되어 프로그램이 실행되는 동안 그대로 유지
#include <iostream>
using namespace std;
class Animal {
public:
void speak() {
cout << "Animal sound" << endl;
}
};
class Dog : public Animal {
public:
void speak() {
cout << "Bark" << endl;
}
};
int main() {
Animal* a = new Dog();
a->speak();
}
동적바인딩
- 대상이 실행 시점에 결정되며 변경될 수 있음
- virtual 키워드 사용
#include <iostream>
using namespace std;
class Animal {
public:
virtual void speak() {
cout << "Animal sound" << endl;
}
};
class Dog : public Animal {
public:
void speak() override {
cout << "Bark" << endl;
}
};
int main() {
Animal* a = new Dog();
a->speak();
}
순수가상함수
- 반드시 자식 클래스에서 구현해야 하는 가상 함수
- 부모 클래스에서는 동작하지 않음. 자식 클래스의 기능을 미리 선언
- 공통 인터페이스는 만들고, 구현은 각자 하게 강제
class Animal {
public:
virtual void speak() = 0;
};
class Dog : public Animal {
public:
void speak() override {
cout << "Bark" << endl;
}
};
추상클래스
- 클래스에 일반함수나 멤버 변수를 가지고 있어도 순수가상함수가 있으면 추상클래스
정적 멤버
- static 키워드 사용
- 클래스에 속하지만 특정 인스턴스에 종속되지 않음 -> 메모리에 한번만 할당되어 모든 인스턴스가 공유할수 있음
- 클래스로 선언하는 객체와는 독립적
- 초기화는 클래스 밖에서 함
class_name::static_variable = 10;
class_name::static_function();
class monster{
public:
static monster* create_monster();
private:
static int mon_count;
};
int monster::mon_count = 0;
가상 소멸자
- 생성자와 소멸자는 특별해서 자식 클래스에서 정의한 생성자와 소멸자는 이름이 달라도 부모 클래스의 생성자와 소멸자를 재정의한것으로 여김
- 소멸자를 가상함수로 저으이하면 업캐스팅 상황에서도 자식 클래스에 정의된 소멸자를 호출할 수 있음.
class monster{
public:
monster();
virtual ~monster();
private:
int *dummy;
};
EX)
#include <iostream>
#include <list>
using namespace std;
class character {
public:
character() :hp(100), power(100) {};
protected:
int hp;
int power;
};
class player :public character{
public:
player() {};
};
class monster {
public:
monster();
virtual ~monster();
virtual void find_route() = 0;
virtual void attack_special(player target_player) = 0;
};
monster::monster() {
cout << "Monster 부모 클래스 생성자" << endl;
}
monster::~monster() {
cout << "Monster 부모 클래스 소멸자" << endl;
}
class monster_a : public monster {
public:
virtual void attack_special(player target_player) override;
virtual void find_route() override;
};
void monster_a::attack_special(player target_player) {
cout << "인탣글 공격 : 데미지 - 15hp" << endl;
}
void monster_a::find_route() {
cout << "깊이 우선 탐색(DFS)" << endl;
}
class monster_b :public monster {
public:
virtual void attack_special(player target_player)override;
virtual void find_route() override;
};
void monster_b::attack_special(player target_player) {
cout << "가상 공격 : 데미지 - 0hp" << endl;
}
void monster_b::find_route() {
cout << "너비 우선 탐색 (BFS)" << endl;
}
class monster_c :public monster {
public:
virtual void attack_special(player target_player) override;
virtual void find_route() override;
};
void monster_c::attack_special(player target_player) {
cout << "강력 뇌전 공격: 데미지 - 100hp" << endl;
}
void monster_c::find_route() {
cout << "다익스트라 최단 경로 알고리즘" << endl;
}
void monster_routine(monster* mon, player target_player) {
mon->find_route();
mon->attack_special(target_player);
}
int main() {
list<monster*> mon_list;
monster_a first_mon;
monster_b second_mon;
monster_c third_mon;
player target_player;
mon_list.push_back(&first_mon);
mon_list.push_back(&second_mon);
mon_list.push_back(&third_mon);
for (auto mon : mon_list) {
monster_routine(mon, target_player);
}
return 0;
}