본문 바로가기
프로그래밍/C++

C++ ] 상속을 이용한 주차타워

by eteo 2022. 6. 24.

 

 

이전에 사용한 동물호텔과 코드가 거의 같다.

 

main.cpp

#include <iostream>
#include "Parking.h"
#include <windows.h>

using namespace std;

int main(void)
{
	Parking parkingHandler;

	while (true)
	{
		int select;

		system("cls");
		parkingHandler.DispMenu();
		cout << "  선택 : [_]\b\b";
		cin >> select;
		
		switch (select)
		{
		case INBOUND:
			parkingHandler.InBound();
			break;
		case OUTBOUND:
			parkingHandler.OutBound();
			break;
		case VIEW:
			parkingHandler.ViewList();
			break;
		case EXIT:
			cout << endl << "  "; return 0;
		default:
			cin.clear();
			cin.ignore(1000, '\n');
			cout << endl << "  잘못 누르셨습니다. 다시 선택해주세요" << endl;
			Sleep(500);
		}
	}
	return 0;
}

 

 

 

Parking.h

#pragma once
#include <cstddef>
#include "Car.h"

#define MAXLOT 8


typedef enum
{
	INBOUND = 1,
	OUTBOUND,
	VIEW,
	EXIT
}_Select;

class Parking
{
private:
	Car* car[MAXLOT];
	int currentCar;

public:
	Parking()
		:currentCar(0)
	{
		for(int i=0; i<MAXLOT;i++)
		{
			car[i] = NULL;
		}
	}

	void DispMenu() const;			// 메뉴 표시
	void InBound();					// 입고
	void OutBound();				// 출고
	void ViewList() const;			// 차량조회

	~Parking()
	{}
};

 

참고로 Parking 과 Car는 has - a 관계에 있다. 멤버변수를 Car 포인터로 정의했기 때문에 사용하기 전에 new로 생성해 줘야하고 delete로 지워 언제든 떼버릴 수 있다.

 

 

 

Car.cpp

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>

using namespace std;

typedef enum {
	SMALLCAR = 1,
	SUV
}_CarType;

class Car
{
private:
	_CarType type;
	char* RegNum;

public:
	Car(_CarType mytype, char* myRegNum)
		:type(mytype)
	{
		RegNum = new char[strlen(myRegNum) + 1];
		strcpy(RegNum, myRegNum);
	}
	 
	char* GetRegNum() const
	{
		return RegNum;
	}

	virtual char* GetTypeToStr() const = 0;

	_CarType GetType() const		// type getter
	{
		return type;
	}
	
	virtual ~Car()				// 가상소멸자
	{
		delete[]RegNum;
	}

};

class Smallcar : public Car
{
public:
	Smallcar(_CarType mytype, char* myRegNum)
		:Car(mytype, myRegNum)
	{}
	
	char* GetTypeToStr() const
	{
		char* s = (char*)"승용차";
		return s;
	}	
};

class Csuv : public Car
{
public:
	Csuv(_CarType mytype, char* myRegNum)
		:Car(mytype, myRegNum)
	{}
	char* GetTypeToStr() const
	{
		char* s = (char*)"SUV";
		return s;
	}
};

 

char* GetTypeToStr() const 함수는 enum type에 따라 char* 형인 "승용차 또는 "SUV" 로 반환하는 함수이다. Car 클래스에는 virtual로 선언했고 Car, Csuv 클래스에서 재정의해주었다.

 

SUV의 클래스명이 Csuv 로 한 이유는 짜다보니 enum인 SUV와 충돌을 일으켜서이다. 처음엔 enum class 로 만들어서 _CarType::SUV 이런식으로 해결하려고 했는데 '==' 등호 사용에 문제가 있어서 일단 클래스명을 Csuv로 만들어 해결했다.

 

아래 글을 보니 enum Class는 형식과 제약의 제한이 있어 사용이 더 까다로운 것 같다.

https://boycoding.tistory.com/180

 

 

 

Parking.cpp

#include "Parking.h"
#include <iostream>
#include <windows.h>
#include <cstdio>

using namespace std;


void Parking::DispMenu() const		// 메뉴 표시
{
	cout << "========== 메뉴 ==========" << endl;
	cout << "|                        |" << endl;
	cout << "| 1. 입고                |" << endl;
	cout << "|                        |" << endl;
	cout << "| 2. 출고                |" << endl;
	cout << "|                        |" << endl;
	cout << "| 3. 차량조회            |" << endl;
	cout << "|                        |" << endl;
	cout << "| 4. 나가기              |" << endl;
	cout << "|                        |" << endl;
	cout << "=========================" << endl;
}



void Parking::InBound()					// 입고
{
	system("cls");

	if(currentCar < MAXLOT)
	{

		cout << endl << "문이 열립니다...차량을 입고시켜 주세요." << endl << endl;

		int select = 0;

		while(1)
		{			

			cout << "차종을 입력해 주세요" << endl << endl;
			cout << "  1. 승용차" << endl << endl;
			cout << "  2. SUV" << endl << endl;
			cout << "  [_]\b\b";
			cin >> select;

			if (select == 1 || select == 2)
			{
				cin.clear();
				cin.ignore(1000, '\n');
				break;
			}
			else
			{
				cin.clear();
				cin.ignore(1000, '\n');
				cout << endl << "잘못 입력하셨습니다. 다시 입력해주세요..." << endl;
				Sleep(500);
			}
		}

		cout << endl << "차량번호를 입력해주세요 : " << endl << endl;
		cout << "  ____\b\b\b\b";
		char* tempName = new char[10];
		cin >> tempName;
		cin.clear();
		cin.ignore(1000, '\n');

		Car* tmpPtr = 0;

		if (select == SMALLCAR) tmpPtr = new Smallcar(SMALLCAR, tempName);
		else if (select == SUV) tmpPtr = new Csuv(SUV, tempName);

		delete[]tempName;

		if (tmpPtr != NULL)							
		{
			// 빈공간 중 가장 앞번호에 차량 입고
			int i;
			for(i=0; i< MAXLOT; i++)
			{
				if (car[i] == NULL) break;
			}
			this->car[i] = tmpPtr;

			cout << endl << "문이 닫힙니다..." << endl;
			cout << endl << "입고가 완료되었습니다..." << endl << endl;
			currentCar++;
			system("pause");
		}

	}else {
		cout << "현재 빈 슬롯이 없어 입고가 불가능 합니다" << endl << endl;
		system("pause");
	}
		
}
void Parking::OutBound()				// 출고
{
	system("cls");

	if (currentCar == 0)
	{
		cout << "현재 입고된 차량이 없습니다." << endl << endl;
		system("pause");
		return;
	}

	cout << "출고할 차량번호를 입력해주세요 : " << endl << endl;
	cout << "  ____\b\b\b\b";

	char* tempName = new char[10];
	cin >> tempName;

	cin.clear();
	cin.ignore(1000, '\n');

	int i;
	int chk = 0;
	for (i = 0; i < MAXLOT; i++)
	{
		if (car[i] != NULL)									
		{
			if (strcmp(car[i]->GetRegNum(), tempName) == 0)
			{
				chk++;							
				break;
			}
		}
	}

	delete[]tempName;						

	if (chk == 1)
	{
		cout << endl << "차량번호 " << car[i]->GetRegNum() << " 를 출고 합니다" << endl << endl;

		delete car[i];								
		car[i] = NULL;								

		currentCar--;
		cout << endl << "문이 열립니다." << endl;
		cout << endl << "출고가 완료되었습니다..." << endl << endl;

		system("pause");

	}
	else if (chk == 0) {						
		cout << endl << "일치하는 차량이 없습니다." << endl << endl;
		system("pause");
	}
	
}
void Parking::ViewList() const			// 차량조회
{
	system("cls");
	printf("== 차량 입고 현황 [ %d대 입고 / 총 %d자리 ] ==\n\n", currentCar, MAXLOT);
	printf("   LOT번호     차종         차량번호\n");
	printf("------------------------------------------\n");

	for (int i = 0; i < MAXLOT; i++)
	{
		if (car[i] == NULL)
		{
			printf("    [%d]         X               X  \n", i + 1);
		}
		else
		{
			// 띄어쓰기 때문에 GetType으로 차종 확인후 GetTypeToStr로 문자열 반환
			if(car[i]->GetType()==SMALLCAR) printf("    [%d]       %s          %s  \n", i + 1, car[i]->GetTypeToStr(), car[i]->GetRegNum());
			else if(car[i]->GetType()==SUV) printf("    [%d]        %s            %s  \n", i + 1, car[i]->GetTypeToStr(), car[i]->GetRegNum());
		}
	}
	printf("------------------------------------------\n\n");
	
	cout << "  ";
	system("pause");
}

 

이전의 동물호텔과 달라진 점은 사용자가 입고할 번호를 입력하는 게 아니라 빈공간 중 앞번호에 자동으로 채워 넣는다. 예를들어 1, 3번 공간만 차있는 상태에서 입고하면 2번에 들어간다.