상속

윤이령·2026년 4월 20일
  • 자식 클래스는 부모 클래스를 대체할 수 있음

단일 상속

class character{
public:
	character() : hp(100), power(100) {}; // 초기화
protected:
	int hp;
    int power;
};

class player : character{
public:
	player(){};
};

다중 상속

class character{
public:
	character() : hp(100), power(100) {}; // 초기화
protected:
	int hp;
    int power;
};

class player : public character {
public:
	player() {};
};

class monster {
public:
	monster() {};
	void get_damage(int damage) {};
	void attack(player target_player) {};
	void attack_special(player target_player);
};

// monster는 public으로, character는 private으로 2개를 상속 받고있음
// public으로 지정하지 않으면 private로 지정됨
class monster_a : public monster, character { 
public:
	void attack_special(player target_player);
};

오버라이딩

class character {
public:
	character() : hp(100), power(100) {};
protected:
	int hp;
	int power;
};

class player : public character {
public:
	player() {};
};

class monster {
public:
	monster() {};
	void get_damage(int damage) {};
	void attack(player target_player) {};
	void attack_special(player target_player);
};

class monster_a : public monster, character {
public:
	//재정의
	void attack_special(player target_player);
};

int main() {
	player player_1;

	monster_a forest_monster;

	cout << "오버라이딩 공격" << endl;
	forest_monster.attack_special(player_1);
    
    cout << "기본 공격" << endl;
    //네임스페이스에 속한 함수 호출 > 부모 함수 호출
    forest_monster.monster::attack_special(player_1);

	return 0;
}

레퍼런스 변수 사용

  • 접근 범위는 상속 여부가 아니라 참조 타입이 결정한다
  • 앞 타입이 접근 가능한 함수/멤버 범위를 제한한다
  • monster& ← monster 또는 monster_a 객체 참조 가능 (업캐스팅)
  • monster_a& ← monster_a 객체만 가능
class character {
public:
	character() : hp(100), power(100) {};
protected:
	int hp;
	int power;
};

class player : public character {
public:
	player() {};
};

class monster {
public:
	monster() {};
	void get_damage(int damage) {};
	void attack(player target_player) {};
	void attack_special(player target_player);
};

void monster::attack_special(player target_player) {
	cout << "기본공격: 데미지 - 10 hp" << endl;
}

class monster_a : public monster, character {
public:
	//재정의
	void attack_special(player target_player);
};

void monster_a::attack_special(player target_player) {
	cout << "인탱글 공격 : 데미지 - 15 hp" << endl;
}

int main() {
	player player_1;

	monster_a forest_monster;

	//monster로 정의했으므로 monster 시점으로만 본다 -> monster 멤버만 접근 가능
    //forest_monster가 monster_a객체이고, monster를 보모로 두고있기 때문에 업캐스팅 가능
	monster &mon = forest_monster;
    mon.attack_special(player_1); // 부모 클래스 호출
    
    //monster_a로 정의했으므로 monster + monster_a 전부 접근 가능
    monster_a &mon_a = forest_monster;
    mon_a.attack_special(player_1); // 자식 클래스 호출

	return 0;
}

가상함수 사용

  • 변수x, 함수O
  • 부모 클래스를 참조하더라도 객체에서 가장 마지막에 오버라이딩 된 함수 호출
  • virtual은 “참조 타입”이 아니라 “실제 객체 타입” 기준으로 함수 실행을 결정
class character {
public:
	character() : hp(100), power(100) {};
protected:
	int hp;
	int power;
};

class player : public character {
public:
	player() {};
};

class monster {
public:
	monster() {};
	void get_damage(int damage) {};
	void attack(player target_player) {};
    //virtual -> 가상함수 선언
	virtual void attack_special(player target_player);
};

void monster::attack_special(player target_player) {
	cout << "기본공격: 데미지 - 10 hp" << endl;
}

class monster_a : public monster, character {
public:
	//재정의
	virtual void attack_special(player target_player) override;
};

void monster_a::attack_special(player target_player) {
	cout << "인탱글 공격 : 데미지 - 15 hp" << endl;
}

int main() {
	player player_1;

	monster_a forest_monster;

	monster &mon = forest_monster;
    // 가상함수를 사용했으므로 monster_a의 함수를 불러옴
    mon.attack_special(player_1); 
    
    monster_a &mon_a = forest_monster;
    mon_a.attack_special(player_1); // 자식 클래스 호출
    
    //네임스페이스로 부모 함수 호출
    mon_a.monster::attack_special(player_1);

	return 0;
}

여러 종류의 객체를 하나의 방식으로 처리하기 위해서다.
1. 자식 클래스가 여럭일경우
class monster {};
class monster_a : public monster {};
class monster_b : public monster {};
class monster_c : public monster {};
2. 레퍼런스를 사용하지 않을 경우 -> 몬스터 종류가 늘어날 때마다 함수 추가 필요
void attack(monster_a a);
void attack(monster_b b);
void attack(monster_c c);
3. 부모 타입의 레퍼런스로 받아옴
-> 업캐스팅으로 자식클래스를 받아올 수 있음
-> virtual 함수가 있을 경우 실제 객체 기준으로 실행됨 (동적 바인딩)
void attack(monster& m) {
m.attack_special();
}
monster_a a;
monster_b b;
monster_c c;
attack(a);
attack(b);
attack(c);

monster& m = forest_monster;
m이 “보는 것”

  • monster에 있는 멤버 변수 ✔
  • monster에 있는 함수 ✔
  • monster에 없는 것 ❌ (원래 못 봄)

reference는 “타입 기준 제한”
monster& = “monster 부분만 보게 만든다”
virtual이면 monster_a에 있는 걸 ‘실행한다’
변수는 virtual 불가

0개의 댓글