C++/C++ 상속

C++ 상속 오버라이딩

재윤 2024. 1. 24. 15:51
반응형

현재

ScavTrap이 ClapTrap을 상속받은 상태

ScavTrap.hpp

#ifndef SCAVTRAP_HPP
# define SCAVTRAP_HPP

# include <iostream>
# include "ClapTrap.hpp"

class ScavTrap : public ClapTrap
{
private:
	std::string name;
	unsigned int hitPoint;
	unsigned int energyPoint;
	unsigned int attackDamage;

public:
	ScavTrap();
	~ScavTrap();
	ScavTrap(std::string name);
	ScavTrap(const ScavTrap& scavTrap);
	ScavTrap& operator=(const ScavTrap& obj);

	void attack(const std::string& target);
	//std::string getName() const;
	void guardGate();
};

# endif

ClapTrap.hpp

#ifndef CLAPTRAP_HPP
# define CLAPTRAP_HPP

# include <iostream>

class ClapTrap{
protected:
	std::string name;
	unsigned int hitPoint;
	unsigned int energyPoint;
	unsigned int attackDamage;

public:
	ClapTrap();
	~ClapTrap();
	ClapTrap(std::string name);
	ClapTrap(const ClapTrap& ClapTrap);
	ClapTrap& operator=(const ClapTrap& obj);
	void attack(const std::string& target);
	void takeDamage(unsigned int amount);
	void beRepaired(unsigned int amount);

	virtual std::string getName() const;
	unsigned int getHitPoint() const;
	unsigned int getEnergyPoint() const;
	unsigned int getAttackDamage() const;
};

# endif

 

어 근데 상속을 열심히 한 사람이면 문제를 바로 알 수 있을 것이다.

바로 → ScavTrap에 같은 변수가 있는 것

이 문제는 나중에 알아보기로 하고!

ClapTrap에서 getName이라는 것이 정의 되어 있다.

main에서 사용해보자

#include "ScavTrap.hpp"

int	main(void)
{
	ScavTrap a("A");
	// ClapTrap b("B");
	ScavTrap c;

	//a = c;
	//std::cout << a.getName() << std::endl;
	//std::cout << c.getName() << std::endl;
	c = a;
	// a.attak("B");
	// std::cout << "a : getAttackDamage " << a.getAttackDamage() << std::endl;
	// std::cout << "a : getEnergyPoint " << a.getEnergyPoint() << std::endl;
	// std::cout << "a : getHitPoint " << a.getHitPoint() << std::endl;
	//b.takeDamage(0);
	//b.takeDamage(2);
	//b.beRepaired(2);
	//b.takeDamage(10);
	//b.takeDamage(50);
	// c.attack("B");
	// c.guardGate();

	return (0);
}
jaeyojun@c2r10s6 ex01 % ./a.out 
ClapTrap basic constructor called
attackad A
attackad 20
ScavTrap A constructor called
ClapTrap basic constructor called
attackad awdawd: basic
attackad : basic
ScavTrap basic destructor called
ClapTrap basic destructor called
ScavTrap A destructor called
ClapTrap basic destructor called

이렇게 결과 나온다.

  • 그런데 attackad awdawd: basic attackad : basic 이 부분이 원래는 a의 name인 “A”이 나와야 하는데 나오지 않는다.
  • 왜냐하면 현재 getName이라는 함수가 부모에서 선언이 되어있는데 오버라이딩이 되지 않아 부모에 있는 변수 name을 불러오기 때문이다.
  • 어? 그러면 부모에 있는 name을 어떻게 자동으로 선언이 되었지? 라고 생각할 수 있는데 main에서 A를 호출한 뒤에 부모에서 자식으로 오는데 자식은 std::string name이라는 생성자가 호출 되었지만 부모에서는 그것을 몰라서 그냥 기본 생성자로 생성을 한다.
  • 그래서 getName을 하게 되면 기본 생성자로 생성된 name basic이 나오게 된다. 그것을 해결해주기 위해

 

ScavTrap.hpp

#ifndef SCAVTRAP_HPP
# define SCAVTRAP_HPP

# include <iostream>
# include "ClapTrap.hpp"

class ScavTrap : public ClapTrap
{
private:
	std::string name;
	unsigned int hitPoint;
	unsigned int energyPoint;
	unsigned int attackDamage;

public:
	ScavTrap();
	~ScavTrap();
	ScavTrap(std::string name);
	ScavTrap(const ScavTrap& scavTrap);
	ScavTrap& operator=(const ScavTrap& obj);

	void attack(const std::string& target);
	std::string getName() const;
	void guardGate();
};

# endif
  • 요렇게 오버라이딩을 해준다. 당연히 ScavTrap.cpp에 다시 선언을 해주어야한다.
  • 저 private이 없으면 그냥 불러도 자식에서 name을 들고온다.
반응형

'C++ > C++ 상속' 카테고리의 다른 글

C++ 상속  (1) 2024.01.24