TIL 2024/8/23

Sung Joo Lee·2024년 8월 23일

상속 Part 4





기본 클래스의 멤버 함수 사용


  • 유도 클래스는 기본 클래스 의 멤버 함수를 직접 호출 가능

    • public / protected인 멤버 함수의 경우에 한함
  • 유도 클래스는 기본 클래스의 멤버 함수를 오버라이드 또는 재정의 가능

  • 다형성의 구현을 위해 중요한 기능

정적 바인딩


  • 타입을 기준으로 함수를 호출하는 것
#include <iostream>

class Entity
{
protected:
	int x, y;
public:
	Entity(int x , int y)
		:x{x},y{y}{}

	void showPosition()
	{
		std::cout << "[" << x << "," << y << "]" << std::endl;
	}

	void talk()
	{
		std::cout << "Hello" << std::endl;
	}
};

class Player :public Entity
{
private:
	int hp, xp, speed;

public:
	Player(int x, int y , int speed)
		: Entity{x,y},speed{speed}{}

	void Move(int dx, int dy)
	{
		x += dx;
		y += dy;
	}

	void talk() // 동일한 함수명 존재
	{
		std::cout << "Hello I'm Player!!" << std::endl;
	}
};

int main()
{
	Player p{ 5,5,10 };
	p.talk();
}

위의 코드에서 Base class와 Derived class가 동일한 이름의 함수 talk()가 존재할 때 어떤 기준으로 호출할 함수를 결정할 것 인가 정해야 한다. → 타입을 기준 호출한다.

  • 즉, p는 Player type의 객체이기 때문에 Player class의 talk가 호출이 된다.

주의


int main()
{
	Player p{ 5,5,10 };
	p.talk();

	Entity e{ 1,1 };
	e = p; //오류 발생 하지 않는다.

	e.talk();

}
  • 위와 같은 상황에서 p는 Player이자 Entity이기 때문에 e에 대입이 가능 하지만 e는 여전히 Entitiy class로 선언이 되었기 때문에 Entity의 talk()가 호출이 된다.

그럼 아래와 같은 상황도 한번 고민해 보자

	Player p{ 5,5,10 };
	p.talk();

	Entity e{ 1,1 };
	e.talk();
	
	Entity* eptr = new Player{1,1,2};
	eptr -> talk(); //???
  • eptr은 Entity type의 포인터이기 때문에 결국에 Player안의 Entity 의 talk를 호출 할 것이다.

Is - A 관계

void TalkSomething(Entity e)
{
	e.talk();
}

void ShowSomething(Entity e)
{
	e.showPosition();
}

int main()
{
	Player p{ 0,0,1 };
	TalkSomething(p); //가능
	ShowSomething(p); //가능
}

- 기본 클래스 객체를 사용하는 곳에는 항상 유도 클래스 객체를 사용 가능
- 유도 클래스에 기본 클래스의 멤버가 모두 포함되기 때문에
- Player 객체는 두 가지 타입을 모두 가진 상태가 됨!

profile
개발로그

0개의 댓글