연재 완료/C++ Lang 예제코드 모음

9. cpp_ex_Polymophism

라이피 (Lypi) 2019. 4. 8. 11:17
반응형
Header.h
#pragma once
#include 
#include 

using std::cout;
using std::cin;
using std::endl;
using std::string;
Animal.h
#pragma once
#include "Header.h"

class Animal
{
protected:
	int speed;

public:
	virtual void  speak() = 0;
	virtual int   walk(int here) = 0;
	
	virtual void  setSpeed(int s) = 0;
	virtual int   getSpeed() = 0;
	virtual void  printSpeed() = 0;

	virtual void  printName() = 0;

public:

	//virtual Animal();		//생성자는 재정의될 수 없으니 가상함수로 만들수도 없다.
	Animal();
	virtual ~Animal();
};


Animal.cpp
#include "Animal.h"

//어차피 오버라이딩 해야하는 함수이므로 이렇게 안에 내용이 있어도 의미가 없다.
//순수 가상으로 정의하고 내용을 만들면?
void   Animal::setSpeed(int s)
{
	speed = s;
}

Animal::Animal()
{
	speed = 0;
}

Animal::~Animal()
{
}
Dog.h
#pragma once
#include "Animal.h"

class Dog :	public Animal
{
private:
	string name;

public:
	//오버라이딩 함수
	//vitual속성은 상속되므로 재정의한 가상 함수는 vitual키워드가 안 붙어있어도 가상함수이다.
	void  speak();
	int   walk(int here);

	void  setSpeed(int s);
	int   getSpeed();
	void  printSpeed();
	
	void  printName();

	//추가한 함수
	virtual void  bite();

public:
	Dog();
	virtual ~Dog();
};


Dog.cpp
#include "Dog.h"

//클래스 외부에서는 virtual키워드를 쓸 수 없다.
void  Dog::speak()
{
	cout << "멍멍" << endl;
}

int   Dog::walk(int here)
{
	return here + speed;

}

void  Dog::setSpeed(int s)
{
	speed = s;
}
int   Dog::getSpeed()
{
	return speed;
}
void  Dog::printSpeed()
{
	cout << speed << endl;
}

void  Dog::printName()
{
	cout << name << endl;
}

void  Dog::bite()
{
	cout << "개는 물수 있다." << endl;
}


Dog::Dog()
{
	name = "개!";
	speed = 3;
}


Dog::~Dog()
{
}

cat.h
#pragma once
#include "Animal.h"

class Cat :	public Animal
{
private:
	string name;

public:
	//오버라이딩 함수
	//vitual속성은 상속되므로 재정의한 가상 함수는 vitual키워드가 안 붙어있어도 가상함수이다.
	void  speak();
	int   walk(int here);

	void  setSpeed(int s);
	int   getSpeed();
	void  printSpeed();

	void  printName();

	//추가한 함수
	virtual void  claw();

public:
	Cat();
	virtual ~Cat();
};


Cat.cpp
#include "Cat.h"

void  Cat::speak()
{
	cout << "야옹" << endl;
}

int   Cat::walk(int here)
{
	return here + speed;
}

void  Cat::setSpeed(int s)
{
	speed = s;
}

int   Cat::getSpeed() 
{
	return speed;
}

void  Cat::printSpeed()
{
	cout << speed << endl;
}

void  Cat::printName()
{
	cout << name << endl;
}

void  Cat::claw()
{
	cout << "고양이는 할퀼 수 있다." << endl;
}

Cat::Cat()
{
	name = "고양이!";
	speed = 4;
}


Cat::~Cat()
{
}

JumpingCat.h
#pragma once
#include "Cat.h"
class JumpingCat :	public Cat
{
private:
	string name;

public:
	//오버라이딩 함수
	//부모에 vitual이 안 붙어있어도 부모의 부모에 붙은 virtual이 상속된다.
	void  speak();
	int   walk(int here);

	void  printName();

	//추가한 함수
	void jump();

public:
	JumpingCat();
	virtual ~JumpingCat();
};


JumpingCat.cpp
#include "JumpingCat.h"

//오버라이딩 함수
void  JumpingCat::speak()
{
	cout << "grrrrrrr" << endl;
}

int   JumpingCat::walk(int here)
{
	//부모의 멤버 변수를 그대로 쓸 수 있다.
	return here + speed;
}

void  JumpingCat::printName()
{
	cout << name << endl;
}

//추가한 함수
void JumpingCat::jump()
{
	cout << "JumpingCat은 점프도 할 수 있다!" << endl;
}

JumpingCat::JumpingCat()
{
	//멤버 변수를 오버라이딩 하면 자식 클래스의 멤버 변수가 부모 클래스의 멤버 변수의 이름을 완전히 가리게된다.
	name = "점핑 캣!";
	//부모의 멤버 변수를 새롭게 초기화해서 그대로 쓸 수 있다.
	speed = 5;
}


JumpingCat::~JumpingCat()
{
}

main.cpp
#include "Dog.h"
#include "JumpingCat.h"

//매개변수를 부모클래스의 참조나 포인터로 받으면 자식 클래스를 다 받을 수 있다.
void temp(Animal& ani)
{
	ani.printSpeed();
}

void temp1(Animal* ani)
{
	ani->printSpeed();
}

//추상클래스를 매개변수로 사용할 수 없다.
//void temp2(Animal ani)
//{
//	ani.printSpeed();
//}


int main()
{
	//추상 클래스로는 객체를 만들 수 없다.
	//Animal ani;

	Animal* ani[3];
	ani[0] = new Dog;
	ani[1] = new Cat;
	ani[2] = new JumpingCat;

	//부모 클래스의 포인터로 자식 클래스를 가리켜서 사용하기 
	for (int iCnt = 0; iCnt < 3; iCnt++) {
		ani[iCnt]->printName();
		ani[iCnt]->speak();
		cout << ani[iCnt]->walk(10) << endl;
		
		//참조를 받는 함수에 포인터를 쓸 수 없다.
		//temp(ani[iCnt]);

		temp1(ani[iCnt]);
	}

	//부모 클래스의 포인터로 자식 클래스의 멤버 함수를 호출할 수는 없다.
	//ani[0]->bite();
	//ani[1]->claw();
	
	//하향 형변환을 하면 가능하다.
	Dog* ani_0 = dynamic_cast (ani[0]);
	ani_0->bite();
	
	Cat c;
	temp(c);

	JumpingCat jc;
	temp1(&jc);
}
반응형