상속

상속은 기존의 클래스를 받아서 기존의 클래스를 포함한 새로운 클래스를 만드는 행위라고 보면된다.

코드

#include "pch.h"
#include <iostream>

class Monster
{
public:
	std::string m_Name;
	int m_HP;
	int m_MP;
    
    	int GetHP()
	{
		return m_HP;
	}

	int GetMP()
	{
		return m_MP;
	}
};

class Fighter : public Monster
{
};

class Archer : public Monster
{
};

class Wizard : public Monster
{
};

int main()
{
	return 0;
}

Monster를 부모클래스
Fighter, Archer, Wizard 를 자식 클래스라고 봤을때
Fighter, Archer, Wizard 는 부모클래스인 Monster의 모든 멤버 변수와 멤버 함수를 물려받는다.

상속을 받는 형식은
class 클래스명 : 상속 접근 지정자 부모클래스명 
ex) class Wizard : public Monster이다.

접근 지정자

접근 지정자는 말 그대로 객체의 멤버 변수, 멤버 함수에 접근할 수 있는 권한이다.

public : 어디서든 접근 가능
private : 기반 클래스에서만 접근 가능
protected : 기반 클래스, 파생 클래스에서 접근 가능

상속 접근 지정자

상속 접근 지정자는 부모로 부터 물려받은 멤버 함수와 멤버 객체를 상속 접근 지정자의 형태로 물려받는걸 의미한다.
주의 해야할점은 부모 클래스(기반 클래스) 에서 private로 물려받은 멤버 변수 및 멤버 함수는 private에서 변형되지 않는다.

우선 순위는 
1. private
2. protected
3. public 

상속 접근 지정자 부모 클래스(기반 클래스) 자식 클래스(파생 클래스)의 상속 형태
public public public
private private
protected protected
private public private
private private
protected private
protected public protected
private private
protected protected

코드

#include "pch.h"
#include <iostream>

class Monster
{
public:
	std::string m_Name;
	int m_HP; //public 외부 접근 가능
private:
	int m_MP; //private 외부 접근 불가능 Monster 클래스에서만 접근 가능
protected:
	int m_DEF; //protected 외부 접근 불가능 Monster 클래스와 Monster클래스의 자식 클래스(파생 클래스)에서만 접근 가능 
public:
	int GetHP()
	{
		return m_HP;
	}

	int GetMP()
	{
		return m_MP;
	}

	virtual void Func()
	{
	}
};

class Fighter : public Monster
{
public:
	void Func() override
	{
		m_HP; //public 외부 접근 가능
		m_MP; //private 외부 접근 불가능 Monster 클래스에서만 접근 가능
		m_DEF; //protected 외부 접근 불가능 Monster 클래스, Fighter클래스, FIghter클래스의 자식 클래스에서 접근 가능
	}
};

class Archer : private Monster
{
public:
	void Func() override
	{
		m_HP; //private 외부 접근 불가능 Monster 클래스 Archer클래스에서 접근 가능
		m_MP; //private 외부 접근 불가능 Monster 클래스에서만 접근 가능
		m_DEF; //private 외부 접근 불가능 Monster 클래스 Archer클래스에서 접근 가능
	}
};

class Wizard : protected Monster
{
public:
	void Func() override
	{
		m_HP; //protected 외부 접근 불가능
		m_MP; //private 외부 접근 불가능 Monster 클래스에서만 접근 가능
		m_DEF; //protcted 외부 접근 불가능 Monster 클래스, Wizard클래스, Wizard클래스의 자식 클래스에서 접근 가능
	}
};

int main()
{
	Monster Temp_Monster;
	Fighter Temp_Fighter;
	Archer Temp_Archer;
	Wizard Temp_Wizard;
	
	Temp_Monster.m_HP; //public 외부에서 접근 가능
	Temp_Monster.m_MP; //priavte 외부에서 접근 불가능
	Temp_Monster.m_DEF; //protected 외부에서 접근 불가능

	Temp_Fighter.m_HP; //public 외부에서 접근 가능
	Temp_Fighter.m_MP; //private 외부에서 접근 불가능
	Temp_Fighter.m_DEF; //potected 외부에서 접근 불가능

	Temp_Archer.m_HP; //private 외부에서 접근 불가능
	Temp_Archer.m_MP; //private 외부에서 접근 불가능
	Temp_Archer.m_DEF; //private 외부에서 접근 불가능

	Temp_Wizard.m_HP; //protected 외부에서 접근 불가능
	Temp_Wizard.m_MP; //private 외부에서 접근 불가능
	Temp_Wizard.m_DEF; //protected 외부에서 접근 불가능

	return 0;
}

Monster의 private 멤버 변수인 m_Mp는 접근이 불가능하다.

외부에서 접근할때를 보면 상속 접근 지정자에 의해 멤버 변수의 접근 제한이 바뀌어 
위와 같이 오류가 발생한다.

접근 지정자를 명시하지않았을때 클래스와 구조체의 기본 접근 지정자가 다르다.

class(클래스) : private
struct(구조체) : public

다형성

다형성은 형태는 같지만 행동은 다른 특징이라고 말할 수 있습니다.

C++에서 다형성을 잘 보여주는 예는 Overriding(오버라이딩), Overloading(오버로딩) 으로 말할 수 있다.

코드

#include "pch.h"
#include <iostream>

class Monster
{
public:
	virtual void Attack()
	{
		std::cout << "나는 Monster 공격합니다." << std::endl;
	}

	virtual ~Monster()
	{
	}
};

class Fighter : public Monster
{
public:
	void Attack() override
	{
		std::cout << "나는 Fighter 공격합니다." << std::endl;
	}
};

class Archer : private Monster
{
public:
	void Attack() override
	{
		std::cout << "나는 Archer 공격합니다." << std::endl;
	}
};

class Wizard : protected Monster
{
public:
	void Attack() override
	{
		std::cout << "나는 Wizard 공격합니다." << std::endl;
	}

	void Func()
	{
		std::cout << "나는 일반 Func입니다." << std::endl;
	}
	void Func(int _Value)
	{
		std::cout << "나는 int를 받는 Func입니다." << std::endl;
	}
	void Func(float _Value)
	{
		std::cout << "나는 float를 받는 Func입니다." << std::endl;
	}
};

int main()
{
	Monster Temp_Monster;
	Fighter Temp_Fighter;
	Archer Temp_Archer;
	Wizard Temp_Wizard;
	
	Temp_Monster.Attack();
	Temp_Fighter.Attack();
	Temp_Archer.Attack();
	Temp_Wizard.Attack();

	std::cout << std::endl;
	Temp_Wizard.Func();
	Temp_Wizard.Func(10);
	Temp_Wizard.Func(10.0f);
	return 0;
}

실행 결과

같은 이름의 Attack()을 호출하고
같은 이름의 Func()를 호출했지만 다른 함수를 호출해주고 있는걸 확인할 수 있습니다.

+ Recent posts