공부 중 메모/수업 예제 (KGCA)

Cpp 다형성 예제(1)

라이피 (Lypi) 2018. 7. 15. 20:31
반응형

Figure.h 

#pragma once
#include <iostream>
using std::cout;
using std::endl;

class Figure //기본 부모 클래스
{
protected:
     int x;       //중심의 x좌표
     int y;       //중심의 y좌표
     int width;   //가로길이
     int height;  //세로길이

public:     
	 void move(int x, int y);
	 void resize(int width, int height);
	 virtual void draw();	//가상함수
	 void shape();          //가상함수가 아님

public:
	Figure();
	Figure(int x, int y, int width, int height);
	virtual ~Figure();
};



Figure.cpp

#include "Figure.h"

void Figure::move(int x, int y)
{
	this->x = x;
	this->y = y;
}

void Figure::resize(int width, int height)
{
	this->width = width;
	this->height = height;
}

void Figure::draw()
{
	cout << "Figure : Draw" << endl;
}

void Figure::shape()
{
	cout << "Figure : shape" << endl;
}

Figure::Figure(int x, int y, int width, int height)
{
	move(x, y);
	resize(width, height);
	cout << "--------Figure 생성자" << endl;
}

Figure::Figure()
{
	cout << "--------Figure 생성자" << endl;
}

Figure::~Figure()
{
	cout << "--------Figure 소멸자" << endl;
}


Ellipse.h

#pragma once #include "Figure.h" class Ellipse : public Figure { public: void draw() override; // override키워드 : 명시적으로 재정의한 함수임을 강조 //void Draw() override; // 이런식의 오타로 인한 실수를 방지할 수 있다. void shape(); // 재정의할 부모의 메소드가 가상함수가 아니면 override 키워드를 쓸 수 없다. //void shape() override; // 이렇게 하면 빨간줄은 안 뜨는데 멤버 함수를 이미 정의했으니 에러가 뜬다. public: Ellipse(); Ellipse(int x, int y, int width, int height); virtual ~Ellipse(); };

Ellipse.cpp

#include "Ellipse.h"

void Ellipse::draw()
{
	cout << "Draw Ellipse : ";
	printf("(%d,%d)", x, y);
	printf("(%d*%d)", width, height);
	cout << endl;
}

void Ellipse::shape()
{
	cout << "Shape Ellipse : 타원" << endl;
}

Ellipse::Ellipse(int x, int y, int width, int height)
{
	move(x, y);
	resize(width, height);
	cout << "--------Ellipse 생성자" << endl;
}

Ellipse::Ellipse()
{
	cout << "--------Ellipse 생성자" << endl;
}


Ellipse::~Ellipse()
{
	cout << "--------Ellipse 소멸자" << endl;
}


Triangle.h

#pragma once
#include "Figure.h"
class Triangle : public Figure
{
public:
	void draw() override;     //오버라이딩
	void shape(); 
public:
	Triangle();
	Triangle(int x, int y, int width, int height);
	virtual ~Triangle();
};


Triangle.cpp

#include "Triangle.h"

void Triangle::draw()
{
	cout << "Draw triangle : ";
	printf("(%d,%d)", x, y);
	printf("(%d*%d)", width, height);
	cout << endl;
}

void Triangle::shape()
{
	cout << "Shape Triangle : 삼각형" << endl;
}

Triangle::Triangle()
{
	cout << "--------Triangle 생성자" << endl;
}

Triangle::Triangle(int x, int y, int width, int height)
	:Figure(x, y, width, height)
{
	cout << "--------Triangle 생성자" << endl;
}

Triangle::~Triangle()
{
	cout << "--------Triangle 소멸자" << endl;
}

Rectangle.h

#pragma once
#include "Figure.h"
class Rectangle : public Figure
{
public:
	void draw() override;      // 오버라이딩
//	void shape() override;     // 이러면 빨간줄이 뜬다.
	void shape();              // 재정의할 부모의 메소드가 가상함수가 아니면 override 키워드를 쓸 수 없다.
public:
	Rectangle();
	Rectangle(int x, int y, int width, int height);
	virtual ~Rectangle();
};

Rectangle.cpp

#include "Rectangle.h"

void Rectangle::draw()
{
	cout << "Draw Rectangle : ";
	printf("(%d,%d)", x, y);
	printf("(%d*%d)", width, height);
	cout << endl;
}

void Rectangle::shape()
{
	cout << "Shape Rectangle : 사각형" << endl;
}


Rectangle::Rectangle()
{
	cout << "--------Rectangle 생성자" << endl;
}

Rectangle::Rectangle(int x, int y, int width, int height)
	:Figure(x, y, width, height)
{
	cout << "--------Rectangle 생성자" << endl;
}

Rectangle::~Rectangle()
{
	cout << "--------Rectangle 소멸자" << endl;
}
main.cpp
 #include "Ellipse.h"
#include "Rectangle.h"
#include "Triangle.h"

int main()
{

	//자식 클래스를 각각 따로 선언.
	Ellipse ellipse(30, 20, 50, 20);
	Triangle triangle(10, 10, 20, 30);
	Rectangle rectangle(20, 30, 10, 20);

	//클래스의 멤버 함수를 각각 호출
	ellipse.draw();
	ellipse.shape();
	triangle.draw();
	triangle.shape();
	rectangle.draw();
	rectangle.shape();

	const int FIGURE = 3; //그냥 선언할 자식 클래스가 몇개인지 명시한 것

	//부모클래스의 포인터로 자식 클래스를 동적할당함. 
	Figure* figures[FIGURE] = {
		new Ellipse(10,10,20,30),
		new Triangle(20,30,10,20),
		new Rectangle(30,20,50,20)
	};

	//부모 클래스 포인터로 자식 클래스의 멤버 함수를 모두 호출. 
	//자식 클래스에서 재정의한 
	for (int i = 0; i < FIGURE; i++) {
		figures[i]->draw();	  //재정의한 부모의 메소드가 가상함수인 경우. 재정의한 자식의 메소드가 호출됨.
		figures[i]->shape();  //재정의한 부모의 메소드가 가상함수가 아닌 경우. 부모의 메소드가 호출됨.
	}

	for (int i = 0; i < FIGURE; i++) {
		delete figures[i];
	}
}


반응형