가상함수 / 동적 바인딩 / 추상 클래스 / 정적 멤버

윤이령·2026년 4월 21일

가상함수

  • 멤버 함수 가운데 자식 클래스에서 오버라이딩해야 하는 함수
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();  // Animal sound
}

동적바인딩

  • 대상이 실행 시점에 결정되며 변경될 수 있음
  • 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();  // Bark
}

순수가상함수

  • 반드시 자식 클래스에서 구현해야 하는 가상 함수
  • 부모 클래스에서는 동작하지 않음. 자식 클래스의 기능을 미리 선언
  • 공통 인터페이스는 만들고, 구현은 각자 하게 강제
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;
}

//전역함수에서 monster 업캐스팅으로 mosnter_a, monster_b, monster_c를 받음
//가상함수로 사용했으므로 업캐스팅했어도 자식 클래스의 함수를 호출함
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;
}

0개의 댓글