다음은 커피자판기로 작동하는 프로그램을 만들기 위해 필요한 두 클래스이다.
class CoffeeVendingMachine { // 커피 자판기를 표현하는 클래스
Container tong[3]; // tong[0]는 커피, tong[1]은 물, tong[2]는 설탕통을 나타냄
void fill(); // 3개의 통을 모두 10으로 채움
void selectEspresso(); // 에스프레소를 선택한 경우, 커피 1, 물 1 소모
void selectAmericano(); // 아메리카노를 선택한 경우, 커피 1, 물 2 소모
void selectSugarCoffee(); // 설탕커피를 선택한 경우, 커피 1, 물 2 소모, 설탕 1 소모
void show(); // 현재 커피, 물, 설탕의 잔량 출력
bool checkInputError(); // 오류 처리를 위해 추가한 멤버 함수
public:
void run(); // 커피 자판기 작동
};
class Container { // 통 하나를 나타내는 클래스
int size; // 현재 저장 량, 최대 저장 가능량은 10
public:
Container() { size = 10; }
void fill(int n); // n 만큼 채우기
bool consume(int n); // n 만큼 소모하기
int getSize(); // 현재 크기 리턴
};
다음과 같이 실행되도록 main() 함수와 CoffeeVendingMachine, Container를 완성하라. 만일 커피, 물, 설탕 중 잔량이 하나라도 부족해 커피를 제공할 수 없는 경우 “재료가 부족합니다.“ 를 출력하라
#include <iostream>
using namespace std;
class Container { // 통 하나를 나타내는 클래스
int size; // 현재 저장 량, 최대 저장 가능량은 10
public:
Container() { size = 10; }
void fill(int n); // n 만큼 채우기
bool consume(int n); // n 만큼 소모하기
int getSize(); // 현재 크기 리턴
};
void Container::fill(int n) {
size = n; // n 만큼 채우기
}
bool Container::consume(int n) {
size -= n; //n만큼 소모
if (size < 0) { //size가 0보다 작으면
size = 0; //0으로 초기화
return false; //false반환
}
else return true; //tre반환
}
int Container::getSize() {
return size;
}
class CoffeeVendingMachine { // 커피 자판기를 표현하는 클래스
Container tong[3]; // tong[0]는 커피, tong[1]은 물, tong[2]는 설탕통을 나타냄
void fill(); // 3개의 통을 모두 10으로 채움
void selectEspresso(); // 에스프레소를 선택한 경우, 커피 1, 물 1 소모
void selectAmericano(); // 아메리카노를 선택한 경우, 커피 1, 물 2 소모
void selectSugarCoffee(); // 설탕커피를 선택한 경우, 커피 1, 물 2 소모, 설탕 1 소모
void show(); // 현재 커피, 물, 설탕의 잔량 출력
bool checkInputError(); // 오류 처리를 위해 추가한 멤버 함수
public:
void run(); // 커피 자판기 작동
};
void CoffeeVendingMachine::fill() {
for (Container& a : tong) {//for each문, &를 안쓰면 깊은복사인데, 값만 복사되므로 주소값이 달라서 안 채워짐.
a.fill(10);
}
show();
}
void CoffeeVendingMachine::selectEspresso() {
bool k = tong[0].consume(1) && tong[1].consume(1);;
if (!k) cout << "원료가 부족합니다." << endl;
else cout << "에스프레소 드세요" << endl;
}
void CoffeeVendingMachine::selectAmericano() {
bool k = tong[0].consume(1) && tong[1].consume(2);;
if (!k) cout << "원료가 부족합니다." << endl;
else cout << "아메리카노 드세요" << endl;
}
void CoffeeVendingMachine::selectSugarCoffee() {
bool k = tong[0].consume(1) && tong[1].consume(2) && tong[2].consume(1);
if (!k) cout << "원료가 부족합니다." << endl;
else cout << "설탕커피 드세요" << endl;
}
void CoffeeVendingMachine::show() {
cout << "커피 " << tong[0].getSize() << ", 물 " << tong[1].getSize() << ", 설탕 " << tong[2].getSize() << endl;
}
bool CoffeeVendingMachine::checkInputError() {
if (cin.fail()) { // 정수대신 문자열이 입력되어 오류가 발생하는 경우 대처.
cin.clear(); //내부 상태 플러그 초기화
cin.ignore(100, '\n'); // 입력버퍼 비움
cout << "메뉴에 있는 숫자만을 입력해주세요." << endl;
return true; // 오류 있음
}
else
return false; // 오류 없음
}
void CoffeeVendingMachine::run() {
cout << "***** 커피자판기를 작동합니다. *****" << endl;
while (true) {
int num;
cout << "메뉴를 눌러주세요(1:에스프레소, 2:아메리카노, 3:설탕커피, 4:잔량보기, 5:채우기)>>";
cin >> num;
if (checkInputError()) {
continue;
}
switch (num) {
case 1:
selectEspresso();
break;
case 2:
selectAmericano();
break;
case 3:
selectSugarCoffee();
break;
case 4:
show();
break;
case 5:
fill();
break;
default:
cout << "메뉴에 있는 숫자만을 입력해주세요." << endl;
break;
}
}
}
int main() {
CoffeeVendingMachine coffeeVendingMachine;
coffeeVendingMachine.run();
return 0;
}
for-each문이란?
for-each 조건문을 사용하면 간단히 반복문을 작성할 수 있다. (auto 사용가능 - 자료형 자동으로 알아서 해준다.)
(arr를 만약에 동적할당하면 for-each 사용이 불가능하다.)
for(int num : arr){
cout << num << endl;
}
여기서 잠깐!
for-each로 위의 arr의 내용을 바꾸고 싶다면, &참조변수를 사용해야한다.
이유) &를 사용하지 않으면 깊은복사인데(깊은 복사: 값만 복사, 얕은 복사: 주소값을 복사) , 값만 복사되므로 주소값이 달라서 안 채워진다.
for(int &num : arr){
num = 10;
}
'언어 > C++' 카테고리의 다른 글
[C++] 상수 멤버 함수 (함수 뒤에 const) (2) | 2023.10.06 |
---|---|
[C++] 연산자 오버로딩 (이항연산자의 매개변수가 하나인 이유) (0) | 2023.10.06 |
[C++] locale이란? (0) | 2023.09.29 |
[C++] 얕은 복사, 깊은 복사 (0) | 2023.09.25 |
[C++] 1. 멤버이니셜라이저(feat. const 변수), 2. 생성자와 소멸자를 이용한 동적할당, 3. this 포인터 (0) | 2023.09.25 |