|
|
[7장 연습문제]
// 7.h
#ifndef HEADER_7_H
#define HEADER_7_H
#include <string>
namespace header_7 {
(소스 코드)
}
// 7_main.cpp
#include "7.h"
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;
using namespace header_7;
(소스 코드)
// 7_func.cpp
#include "7.h"
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;
namespace header_7 {
(소스 코드)
}
// 1
// 7.h
class Book {
std::string name;
int price, page;
public:
Book(std::string name, int price, int page);
Book& operator+=(int amount);
Book& operator-=(int amount);
void show();
};
// 7_main.cpp
int main() {
Book a("청춘", 20000, 300), b("미래", 30000, 50);
a += 500; b -= 500;
a.show(); b.show();
}
// 7_func.cpp
Book::Book(std::string name, int price, int page) {
this->name = name;
this->price = price;
this->page = page;
}
Book& Book::operator+=(int amount) {
this->price += amount; return *this;
}
Book& Book::operator-=(int amount) {
this->price -= amount; return *this;
}
void Book::show() {
std::cout << name << " " << price << "원 " << page << "페이지" << std::endl;
}
}
// 2
// 7.h
class Book {
std::string name;
int price, page;
public:
Book(std::string name, int price, int page);
Book& operator+=(int amount);
Book& operator-=(int amount);
void show();
friend bool operator==( Book& b1, Book& b2);
friend bool operator==( Book& b, int p);
friend bool operator==( Book& b, std::string n);
};
// 7_main.cpp
int main() {
Book a("명품 C++", 30000, 500), b("고품 C++", 30000, 500);
if (a == 30000) cout << "정가 30000원" << endl;
if (a == "명품 C++") cout << "명품 C++ 입니다." << endl;
if (a == b) cout << "두 책이 같은 책입니다." << endl;
}
// 7_func.cpp
Book::Book(std::string name, int price, int page) {
this->name = name;
this->price = price;
this->page = page;
}
Book& Book::operator+=(int amount) {
this->price += amount; return *this;
}
Book& Book::operator-=(int amount) {
this->price -= amount; return *this;
}
void Book::show() {
std::cout << name << " " << price << "원 " << page << "페이지" << std::endl;
}
bool operator==(Book& b1, Book& b2) {
return (b1.name == b2.name && b1.price == b2.price && b1.page == b2.page);
}
bool operator==(Book& b, int p) {
return (b.price == p);
}
bool operator==(Book& b, std::string n) {
return (b.name == n);
}
}
// 3
// 7.h
class Book {
std::string name;
int price, page;
public:
Book(std::string name, int price, int page);
Book& operator+=(int amount);
Book& operator-=(int amount);
void show();
friend bool operator==( Book& b1, Book& b2);
friend bool operator==( Book& b, int p);
friend bool operator==( Book& b, std::string n);
friend bool operator!(Book& b1);
};
// 7_main.cpp
int main() {
Book book("벼룩시장", 0, 50);
if (!book) cout << "공짜다" << endl;
}
// 7_func.cpp
Book::Book(std::string name, int price, int page) {
this->name = name;
this->price = price;
this->page = page;
}
Book& Book::operator+=(int amount) {
this->price += amount; return *this;
}
Book& Book::operator-=(int amount) {
this->price -= amount; return *this;
}
void Book::show() {
std::cout << name << " " << price << "원 " << page << "페이지" << std::endl;
} bool operator==(Book& b1, Book& b2) {
return (b1.name == b2.name && b1.price == b2.price && b1.page == b2.page);
}
bool operator==(Book& b, int p) {
return (b.price == p);
}
bool operator==(Book& b, std::string n) {
return (b.name == n);
}
bool operator!(Book& b1) { return (b1.price == 0); }
}
// 4
// 7.h
class Book {
std::string name;
int price, page;
public:
Book(std::string name, int price, int page);
Book& operator+=(int amount);
Book& operator-=(int amount);
void show();
friend bool operator==( Book& b1, Book& b2);
friend bool operator==( Book& b, int p);
friend bool operator==( Book& b, std::string n);
friend bool operator!(Book& b1);
std::string gettitle();
friend bool operator<(std::string a, Book& b2);
};
// 7_main.cpp
int main() {
Book a("청춘", 20000, 300);
string b;
cout << "책 이름을 입력하세요.";
getline(cin, b);
if (b < a)
cout << a.gettitle() << "이 " << b << "보다 뒤에 있다." << endl;
}
// 7_func.cpp
Book::Book(std::string name, int price, int page) {
this->name = name;
this->price = price;
this->page = page;
}
Book& Book::operator+=(int amount) {
this->price += amount; return *this;
}
Book& Book::operator-=(int amount) {
this->price -= amount; return *this;
}
void Book::show() {
std::cout << name << " " << price << "원 " << page << "페이지" << std::endl;
}
bool operator==(Book& b1, Book& b2) {
return (b1.name == b2.name && b1.price == b2.price && b1.page == b2.page);
}
bool operator==(Book& b, int p) {
return (b.price == p);
}
bool operator==(Book& b, std::string n) {
return (b.name == n);
}
bool operator!(Book& b1) { return (b1.price == 0); }
std::string Book::gettitle() { return name; }
bool operator<(string a, Book& b2) {
return a < b2.name;
}
}
// 5
// 7.h
class Mat {
int arr[4];
public:
Mat(int a = 0, int b = 0, int c = 0, int d = 0);
Mat& operator+=(const Mat& b);
friend Mat operator+( Mat& b1, Mat& b2);
friend bool operator==( Mat& b1, Mat& b2);
void show();
};
// 7_main.cpp
int main() {
Mat a(1, 2, 3, 4), b(2, 3, 4, 5), c;
c = a + b;
a += b;
a.show(); b.show(); c.show();
if (a == c)
cout << "a와 c는 같다." << endl;
}
// 7_func.cpp
Mat::Mat(int a, int b, int c, int d) {
arr[0] = a; arr[1] = b; arr[2] = c; arr[3] = d;
}
Mat& Mat::operator+=(const Mat& b) {
for (int i = 0; i < 4; i++) this->arr[i] += b.arr[i];
return *this;
}
Mat operator+(Mat& b1, Mat& b2) {
Mat res(0, 0, 0, 0);
for (int i = 0; i < 4; i++) {
res.arr[i] = b1.arr[i] + b2.arr[i];
}
return res;
}
bool operator==(Mat& b1, Mat& b2) {
for (int i = 0; i < 4; i++) {
if (b1.arr[i] != b2.arr[i]) return false;
}
return true;
}
void Mat::show() {
std::cout << "Matrix = { ";
std::cout << arr[0] << " " << arr[1] << " " << arr[2] << " " << arr[3] << " }" << std::endl;
}
// 6
// 7.h
class Mat {
int arr[4];
public:
Mat(int a = 0, int b = 0, int c = 0, int d = 0);
Mat& operator+=(const Mat& b);
friend Mat operator+( Mat& b1, Mat& b2);
friend bool operator==( Mat& b1, Mat& b2);
void show();
friend void operator>>(Mat& m, int* arr);
friend void operator<<(Mat& m, int* arr);
};
// 7_main.cpp
int main() {
Mat a(4, 3, 2, 1), b;
int x[4], y[4] = { 1, 2, 3, 4 };
a >> x;
b << y;
for (int i = 0; i < 4; i++) cout << x[i] << ' ';
cout << endl;
b.show();
}
// 7_func.cpp
void operator>>(Mat& m, int* arr) {
for (int i = 0; i < 4; i++) arr[i] = m.arr[i];
}
void operator<<(Mat& m, int* arr) {
for (int i = 0; i < 4; i++) m.arr[i] = arr[i];
}
// 7
// 7.h
class Circle {
int radius;
public:
Circle(int r);
void show();
Circle& operator++();
};
// 7_main.cpp
int main() {
Circle a(5), b(4);
++a;
b = ++a;
a.show();
b.show();
}
// 7_func.cpp
Circle::Circle(int r) { radius = r; }
Circle& Circle::operator++() { radius++; return *this; }
void Circle::show() { cout << "반지름: " << radius << endl; }
// 8
// 7.h
class Circle {
int radius;
public:
Circle(int r);
void show();
Circle& operator++();
friend Circle operator+(int n, Circle c);
};
// 7_main.cpp
int main() {
Circle a(5), b(4);
b = 1 + a;
a.show();
b.show();
}
// 7_func.cpp
Circle operator+(int n, Circle c) {
return Circle(n + c.radius);
}
// 9
// 7.h
class Statistic {
int* data;
int count;
int capacity;
public:
Statistic();
~Statistic();
bool operator!();
Statistic& operator<<(int n);
void operator~();
void operator>>(int& avg);
};
// 7_main.cpp
int main() {
Statistic stat;
if (!stat) cout << "현재 통계 데이터가 없습니다." << endl;
int x[5];
cout << "5 개의 정수를 입력하라>>";
for (int i = 0; i < 5; i++) cin >> x[i];
for (int i = 0; i < 5; i++) stat << x[i];
stat << 100 << 200;
~stat;
int avg;
stat >> avg;
cout << "avg " << avg << endl;
}
// 7_func.cpp
Statistic::Statistic() {
count = 0; capacity = 1; data = new int[capacity];
}
Statistic::~Statistic() { delete[] data; }
bool Statistic::operator!() { return (count == 0); }
Statistic& Statistic::operator<<(int n) {
if (count == capacity) {
capacity *= 2;
int* temp = new int[capacity];
for (int i = 0; i < count; i++) temp[i] = data[i];
delete[] data; data = temp; }
data[count++] = n; return *this;
}
void Statistic::operator~() {
for (int i = 0; i < count; i++) cout << data[i] << (i == count - 1 ? "" : " ");
cout << endl;
}
void Statistic::operator>>(int& avg) {
if (count == 0) { avg = 0; return; }
int sum = 0;
for (int i = 0; i < count; i++) sum += data[i];
avg = sum / count;
}
// 10
// 7.h
class SortedArray {
int size;
int* p;
void sort();
public:
SortedArray();
SortedArray(SortedArray& src);
SortedArray(int p[], int size);
~SortedArray();
SortedArray operator+(SortedArray& op2);
SortedArray& operator=(const SortedArray& op2);
void show();
};
// 7_main.cpp
int main() {
int n[] = { 2, 20, 6 };
int m[] = { 10, 7, 8, 30 };
SortedArray a(n, 3), b(m, 4), c;
c = a + b;
a.show();
b.show();
c.show();
}
// 7_func.cpp
void SortedArray::sort() {
for (int i = 0; i < size - 1; i++) {
for (int j = i + 1; j < size; j++) {
if (p[i] > p[j]) {
int temp = p[i]; p[i] = p[j]; p[j] = temp;}}}}
SortedArray::SortedArray() : size(0), p(nullptr) {}
SortedArray::SortedArray(int arr[], int s) {
size = s;
p = new int[size];
for (int i = 0; i < size; i++) p[i] = arr[i];
sort();
}
SortedArray::SortedArray(SortedArray& src) {
this->size = src.size;
this->p = new int[size];
for (int i = 0; i < size; i++) this->p[i] = src.p[i];
}
SortedArray::~SortedArray() {
if (p != nullptr) delete[] p;
}
SortedArray SortedArray::operator+(SortedArray& op2) {
int newSize = this->size + op2.size;
int* newArr = new int[newSize];
for (int i = 0; i < this->size; i++) newArr[i] = this->p[i];
for (int i = 0; i < op2.size; i++) newArr[this->size + i] = op2.p[i];
SortedArray temp(newArr, newSize);
delete[] newArr;
return temp;
}
SortedArray& SortedArray::operator=(const SortedArray& op2) {
if (this == &op2) return *this;
delete[] p;
this->size = op2.size;
this->p = new int[size];
for (int i = 0; i < size; i++) this->p[i] = op2.p[i];
return *this;
}
void SortedArray::show() {
cout << "배열 출력 : ";
for (int i = 0; i < size; i++) cout << p[i] << " ";
cout << endl;
}
// [7장 정리문제]
// 1) C++ 의 연산자와 C 언어의 연산자의 처리방식의 차이는 무엇인가
// C언어의 연산자는 정해진 타입에만 동작하는 고정된 부호이고,
// C++의 연산자는 우리가 객체에 맞게 기능을 설계할 수 있는 기호를 이름으로 가지는 함수이다.
// 2) 연산자 함수의 장점은 무엇인가
// 수학적 개념을 다루는 객체에서 함수 호출 대신 a + b라는 수식을 그대로 사용할 수 있어 코드를 실제 수학적 수식과
비슷하게 만들어 가독성을 높인다.
// 사용자 정의 객체가 기본 자료형과 동일한 문법 체계로 작동하게 되는데 이는 템플릿 프로그래밍에서 핵심적인 역할을 한다.
// 예로, std::sort나 다양한 STL 알고리즘들은 내부적으로 <, == 등의 연산자를 사용하므로, 연산자 함수를 통해 이들과
매끄럽게 호환되는 코드를 작성할 수 있게 된다
// 3) 연산자 함수를 정의하는 2 가지 방법을 설명하라
// 1. 클래스 내부에 연산자 함수를 선언해 클래스의 멤버 함수로 정의하는 방법이 있다. 이항 연산자의 경우, 왼쪽에 위치한
피연산자가 함수를 호출하는 주체가 된다.
// 예로, A + B라는 식을 작성하면, 컴파일러는 이를 A.operator+(B)로 해석하여 오른쪽에 있는 B를 함수의 인자로 전달받아
처리하며 클래스의 내부 데이터를 직접 다루기 때문에 코드가 간결해진다.
// 2. 특정 클래스에 소속되지 않은 독립적인 전역 함수로 정의하여 방식으로 연산에 참여하는 모든 피연산자를 함수의
매개변수로 명시해야 한다.
// 따라서 A + B는 operator+(A, B)를 호출하게 된다. 함수가 클래스 밖에 존재하기 때문에, 클래스의 private 멤버에
접근하려면 클래스 내부에서 해당 전역 함수를 friend로 등록해주어야 한다.
// 클래스 객체와 기본 자료형 간의 연산처럼 호출 관계가 대칭적이어야 할 때 이 방식을 사용한다.
// 4) 연산자함수를 프렌드 함수로만 선언해야 하는 경우를 설명하라
// 표준 입출력 스트림 연산자(<< , >> )를 오버로딩할 경우 이 연산에서 좌항은 std::ostream 타입의 객체(cout)이고, 우항이
우리가 만든 클래스 객체가 된다.
// 따라서 전역 함수를 정의하고, 우리 클래스의 private 멤버를 출력하기 위해 클래스 내부에 friend 선언을 해주어야 한다.
// 즉 연산자 함수의 호출 주체인 좌항의 코드를 수정할 권한이 없을 때 전역 함수로 선언하여 정의한 뒤 friend를 사용하여
데이터 접근 권한을 얻게 하는 것이다.
// 5) 연산자함수 중에서 반환형을 참조형으로 선언해야 하는 경우는 어떤 경우인가
// 연산자 함수에서 반환형을 참조형으로 선언해야 하는 경우는 연산의 결과값을 자기 자신에게 바로 대입해야 할 때나
연산자가 좌항에 위치하여 계속해서 수정되어야 할 때,
// 그리고 같은 연산자가 한 라인에서 반복적으로 호출되어 자기 자신을 연속해서 반환하며 작업을 이어가야 할 때이다.
// 6) 전위++, += 연산자 등은 왜 참조를 리턴해야 하는가
// 전위 증감이나 복합 대입 연산자는 연산의 결과가 새로운 제3의 값을 만드는 것이 아니라, 이미 존재하는 자기 자신의
상태를 변경하는 것이므로 참조를 리턴하면 연산이 끝난 후 변경된 객체의 주소를 그대로 반환하므로
// 불필요한 복사본을 만드는 메모리 낭비가 없고, 반환된 값이 원본이기 때문에 (++a).show()처럼 연산 결과에 곧바로 다른
멤버 함수를 호출하거나 추가 연산을 이어갈 수 있다.
// 7) a++++, a 는 문법 오류입니다.이유를 설명하시오
// 후위 증감 연산자는 변경되기 전의 값을 전달하므로, 원본의 주소가 아닌 원본을 복사한 임시 객체를 반환한다.
// 따라서 문법적으로 임시 객체는 수정이 불가능하고, 여기에 다시 ++를 붙이는 것은 임시객체(상수)를 수정하라는 의미가
되어 오류가 난다.
// 8) ++++a, a 는 정상입니다.이유를 설명 하시오
// 전위 증감 연산자는 값을 먼저 증가시킨 후, 증가된 원본 객체 그 자체를 반환하므로 반환된 결과물이 객체이기 때문에,
그 뒤에 다시 ++를 붙여 다른 함수를 호출할 수 있다.
// 즉, ++(++a)는 a를 1 증가시키고, 그 결과인 a를 다시 1 증가시키는 것이 되어 원본 a가 정상적으로 두 번 증가하게 된다.
[8장 연습문제]
// 8.h
#ifndef HEADER_8_H
#define HEADER_8_H
#include <string>
namespace header_8 {
(소스 코드)
}
// 8_main.cpp
#include "8.h"
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;
using namespace header_8;
(소스 코드)
// 8_func.cpp
#include "8.h"
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;
namespace header_8 {
(소스 코드)
}
// 1
// 8.h
class Circle {
int r;
public:
Circle(int r = 0); // 변수 초기화
int getr(); // 변수 값 반환
void putr(int r); // 변수 값 수정
double getarea(); // 반지름이 r인 원의 넓이 반환
};
class Namedcircle : public Circle {
std::string name;
public:
Namedcircle(int r = 0, std::string name = ""); // r은 circle의 생성자에, name 초기화
void show();// 반지름이 r인 원의 이름 과 같이 출력
};
// 8_main.cpp
int main() {
Namedcircle waffle(3, "waffle");
waffle.show();
}
// 8_func.cpp
Circle::Circle(int r) : r(r) {}
int Circle::getr() { return r; }
void Circle::putr(int r) { this->r = r; }
double Circle::getarea() { return 3.14 * r * r; }
Namedcircle::Namedcircle(int r, string name) : Circle(r), name(name) {}
void Namedcircle::show() {
std::cout << "반지름이 " << getr() << "인 " << name << endl;
}
// 2
// 8.h
class Circle {
int r;
public:
Circle(int r = 0); // 변수 초기화
int getr(); // 변수 값 반환
void putr(int r); // 변수 값 수정
double getarea(); // 반지름이 r인 원의 넓이 반환
};
class Namedcircle : public Circle {
std::string name;
public:
Namedcircle(int r = 0, std::string name = ""); // r은 circle의 생성자에, name 초기화
void show();// 반지름이 r인 원의 이름 과 같이 출력
void putname(std::string name);
std::string getname();
};
// 8_main.cpp
int main() {
Namedcircle pizza[5];
int big = 0;
cout << "5 개의 정수 반지름과 원의 이름을 입력하세요" << endl;
for (int i = 0; i < 5; i++) {
int r; string name;
cout << i + 1 << ">> ";
cin >> r >> name;
pizza[i].putr(r); pizza[i].putname(name);
}
for (int i = 0; i < 5; i++) {
if (pizza[i].getarea() > pizza[big].getarea())
big = i;
}
cout << "가장 면적이 큰 피자는 " << pizza[big].getname() << "입니다.";
}
// 8_func.cpp
Circle::Circle(int r) : r(r) {}
int Circle::getr() { return r; }
void Circle::putr(int r) { this->r = r; }
double Circle::getarea() { return 3.14 * r * r; }
Namedcircle::Namedcircle(int r, string name) : Circle(r), name(name) {}
void Namedcircle::show() {
std::cout << "반지름이 " << getr() << "인 " << name << endl;
}
void Namedcircle::putname(string name) { this->name = name; }
string Namedcircle::getname() { return name; }
// 3
// 8.h
class Point {
int x, y;
public:
Point(int x, int y);// 변수 값 초기화
int getx();// 변수 값 변경
int gety();// 변수 값 변경
protected:
void move(int x, int y); // 변수 값 변경
};
class Colorpoint : public Point {
std::string color;
public:
Colorpoint(int x = 0, int y = 0, std::string color = "Black");
void setp(int x, int y);
void setcolor(std::string color);
void show(); // ** 색으로 (x , y)에 위치한 점입니다.
};
// 8_main.cpp
int main() {
Colorpoint a;
a.show();
Colorpoint b;
b.setp(10, 20);
b.setcolor("Blue");
b.show();
}
// 8_func.cpp
Point::Point(int x, int y) : x(x), y(y) {}
int Point::getx() { return x; }
int Point::gety() { return y; }
void Point::move(int x, int y) { this->x = x; this->y = y; }
Colorpoint::Colorpoint(int x, int y, string color) : Point(x, y), color(color) {}
void Colorpoint::setp(int x, int y) { move(x, y); }
void Colorpoint::setcolor(string color) { this->color = color; }
void Colorpoint::show() {
cout << color << "색으로 (" << getx() << ", ";
cout << gety() << ")에 위치한 점입니다." << endl; }
// 4
// 8.h
class Basearr {
int cap;
int* mem;
public:
Basearr(int cap = 100);
~Basearr();
void put(int index, int val);
int get(int index);
int getcap();
};
class Myp : public Basearr {
int outcursor = 0;
int incursor = 0;
public:
Myp(int n);
void enq(int n);
int deq();
int getlength();
};
// 8_main.cpp
int main() {
Myp q(100);
int n;
cout << "큐에 삽입할 5개의 정수를 입력하라>> ";
for (int i = 0; i < 5; i++) {
cin >> n;q.enq(n);
}
cout << "큐의 용량:" << q.getcap() << ", 큐의 크기:" << q.getlength() << endl;
cout << "큐 비우기>> ";
while (q.getlength() != 0) {
cout << q.deq() << ' ';
}
cout << "큐의 현재 크기 : " << q.getlength() << endl;
}
// 8_func.cpp
Basearr::Basearr(int cap) : cap(cap) { mem = new int[cap]; }
Basearr::~Basearr() { delete[] mem; }
void Basearr::put(int index, int val) { mem[index] = val; }
int Basearr::get(int index) { return mem[index]; }
int Basearr::getcap() { return cap; }
Myp::Myp(int n) : Basearr(n) {}
void Myp::enq(int n) { put(incursor++, n); }
int Myp::deq() { return get(outcursor++); }
int Myp::getlength() { return incursor - outcursor; }
// 5
// 8.h
class Basearr {
int cap;
int* mem;
public:
Basearr(int cap = 100);
~Basearr();
void put(int index, int val);
int get(int index);
int getcap();
};
class Mystack : public Basearr {
int cursor = 0;
public:
Mystack(int n);
void enstack(int n);
int destack();
int getcursor();
};
// 8_main.cpp
int main() {
Mystack stack(100);
int n;
cout << "스택에 삽입할 5개의 정수를 입력하라>> ";
for (int i = 0; i < 5; i++) {
cin >> n; stack.enstack(n);
}
cout << "스택의 용량:" << stack.getcap() << ", 스택의 크기:" << stack.getcursor() << endl;
cout << "스택 비우기>> ";
while (stack.getcursor() != 0) {
cout << stack.destack() << ' ';
}
cout << "스택의 현재 크기 : " << stack.getcursor() << endl;
}
// 8_func.cpp
Mystack::Mystack(int n) : Basearr(n), cursor(0) {}
void Mystack::enstack(int n) { put(cursor++, n); }
int Mystack::destack() { return get(--cursor); }
int Mystack::getcursor() { return cursor; }
// 6
// 8.h
class Basemem {
char* mem;
protected:
Basemem(int size);
~Basemem();
void in(int index , char val);
char out(int index);
};
class Rom : public Basemem {
public:
Rom(int size, char* val, int len);
char read(int index);
};
class Ram : public Basemem {
public:
Ram(int size);
void write(int index, char val);
char read(int index);
};
// 8_main.cpp
int main() {
char x[5] = { 'h', 'e', 'l', 'l', 'o' };
Rom rom(100, x, 5);
Ram ram(1024);
for (int i = 0; i < 5; i++)ram.write(i, rom.read(i));
for (int i = 0; i < 5; i++)cout << ram.read(i);
}
// 8_func.cpp
Basemem::Basemem(int size) { mem = new char[size]; }
Basemem::~Basemem() { delete[] mem; }
void Basemem::in(int index, char val) { mem[index] = val; }
char Basemem::out(int index) { return mem[index]; }
Rom::Rom(int size, char* val, int len) : Basemem(size) {
for (int i = 0; i < len; i++) in(i, val[i]); }
char Rom::read(int index) { return out(index); }
Ram::Ram(int size) : Basemem(size) {}
void Ram::write(int index, char val) { in(index, val); }
char Ram::read(int index) { return out(index); }
// 7
// 8.h
class Printer {
std::string model, manufac;
int printedcnt = 0, leastpaper;
public:
Printer(std::string model, std::string manufac, int leastpaper);
void print(int papers); // 정상처리 후 프린트하였습니다 출력. 오류 시 용지부족 멘트 출력
void show();
};
class InkjetPrinter : public Printer {
int Ink;
public:
InkjetPrinter(std::string model, std::string manufac, int leastpaper, int Ink);
void printInk(int papers); // 오류 시 잉크부족 멘트 출력
void info();
};
class LaserPrinter : public Printer {
int toner;
public:
LaserPrinter(std::string model, std::string manufac, int leastpaper, int toner);
void printLaser(int papers); // 오류 시 토너부족 멘트 출력
void info();
};
// 8_main.cpp
int main() {
InkjetPrinter ink("kdjskj", "dskn", 5, 10);
LaserPrinter laser("jdns", "wdu", 3, 20);
cout << "잉크젯 : "; ink.info();
cout << endl << "레이저 : ";
laser.info(); cout << endl;
while (1) {
int model, n;
cout << "프린터(1:잉크젯, 2:레이저)와 매수 입력>>";
cin >> model >> n;
if (model == 1) ink.printInk(n);
else if (model == 2) laser.printLaser(n);
ink.info(); cout << endl;
laser.info(); cout << endl;
cout << "계속 프린트하시겠습니까(y/n)>>";
char x;
cin >> x;
if (x == 'n') break;
}
}
// 8_func.cpp
Printer::Printer(string model, string manufac, int leastpaper)
: model(model), manufac(manufac), leastpaper(leastpaper), printedcnt(0) {}
void Printer::print(int papers) {
if (leastpaper >= papers) {
leastpaper -= papers; printedcnt += papers; cout << "프린트하였습니다.\n"; }
else cout << "용지가 부족하여 프린트할 수 없습니다." << endl;
}
void Printer::show() {
cout << model << " , " << manufac << " , 남은 용지 " << leastpaper << "장"; }
InkjetPrinter::InkjetPrinter(string model, string manufac, int leastpaper, int Ink)
: Printer(model, manufac, leastpaper), Ink(Ink) {}
void InkjetPrinter::printInk(int papers) {
if (Ink < papers) cout << "잉크가 부족하여 프린트할 수 없습니다." << endl;
else { Ink -= papers; print(papers); }
}
void InkjetPrinter::info() { show(); cout << " , 남은 잉크 " << Ink; }
LaserPrinter::LaserPrinter(string model, string manufac, int leastpaper, int toner)
: Printer(model, manufac, leastpaper), toner(toner) {}
void LaserPrinter::printLaser(int papers) {
if (toner < papers) cout << "토너가 부족하여 프린트할 수 없습니다." << endl;
else { toner -= papers; print(papers); }
}
void LaserPrinter::info() { show(); cout << " , 남은 토너 " << toner; }
// 8
// 8.h
class Plane {
std::string seat[8];
public:
Plane();
void show();
void setSeat(int s, std::string name);
void resetSeat(int s);
std::string getSeat(int s);
};
class Daybook {
Plane plane[3];
public:
void showAll();
void showPlane(int t);
void reserve(int t, int s, std::string name);
void cancel(int t, int s);
};
class Console {
Daybook today;
enum { MENU, BOOK, CANCEL, SHOW, EXIT };
typedef void (Console::* ConsoleMemPtr)();
public:
void run();
void menu();
void book();
void cancel();
void show();
void exit();
};
// 8_main.cpp
int main() {
Console console;
console.run();
return 0;
}
// 8_func.cpp
Plane::Plane() { for (int i = 0; i < 8; i++) seat[i] = "---"; }
void Plane::show() { for (int i = 0; i < 8; i++)
std::cout << i + 1 << ":" << seat[i] << "\t"; std::cout << std::endl; }
void Plane::setSeat(int s, std::string name) { seat[s] = name; }
void Plane::resetSeat(int s) { seat[s] = "---"; }
std::string Plane::getSeat(int s) { return seat[s]; }
void Daybook::showAll() {
std::string t[] = { "07시", "12시", "17시" };
for (int i = 0; i < 3; i++) {
std::cout << t[i] << ":\t"; plane[i].show(); }
}
void Daybook::showPlane(int t) {
std::string times[] = { "07시", "12시", "17시" };
std::cout << times[t] << ":\t"; plane[t].show();
}
void Daybook::reserve(int t, int s, std::string name) {
plane[t].setSeat(s, name); }
void Daybook::cancel(int t, int s) { plane[t].resetSeat(s); }
void Console::menu() { std::cout << "\n예약(1), 취소(2), 보기(3), 끝내기(4) >> "; }
void Console::show() { today.showAll(); }
void Console::exit() { std::cout << "프로그램을 종료합니다." << std::endl; }
void Console::book() {
int t, s; std::string name;
std::cout << "시간(1:07시, 2:12시, 3:17시)>>"; std::cin >> t;
today.showPlane(t - 1);
std::cout << "좌석번호>>"; std::cin >> s;
std::cout << "이름>>"; std::cin >> name;
today.reserve(t - 1, s - 1, name);
}
void Console::cancel() {
int t, s;
std::cout << "시간(1:07시, 2:12시, 3:17시)>>"; std::cin >> t;
today.showPlane(t - 1);
std::cout << "좌석번호>>"; std::cin >> s;
today.cancel(t - 1, s - 1);
}
void Console::run() {
ConsoleMemPtr handlers[] = { &Console::menu, &Console::book,
&Console::cancel, &Console::show, &Console::exit };
int sel;
while (true) {
(this->*handlers[MENU])();
if (!(std::cin >> sel)) {
std::cin.clear(); std::cin.ignore(100, '\n');
std::cout << "숫자(1~4)만 입력해 주세요!" << std::endl;
continue; }
if (sel >= BOOK && sel <= EXIT) {
(this->*handlers[sel])(); if (sel == EXIT) break; }
else std::cout << "1~4 사이의 메뉴 번호를 선택해 주세요." << std::endl;
}
}
// [8장 정리문제]
// 1) 상속이 왜 필요한가
// 상속은 코드의 재사용과 효율적인 관리를 위해서 필요하다. 상속을 이용하면 공통된 특성을 부모 클래스에 한 번만
정의해두고, 자식 클래스는 그걸 그대로 이어받게 한 후 필요에 따라 기능을 추가함으로써 코드 중복이 획기적으로 줄어들고,
이후 수정 사항이 생기면 부모 클래스만 수정해도 자식 클래스에게도 적용되어 유지보수도 훨씬 편해진다.
// 2) 상속을 구현할 때 기본클래스에 넣어야 하는 기능과, 파생클래스에 넣어야 하는 기능을 어떻게 구분하는가
// 기본 클래스는 여러 객체들이 공통적으로 가지고 있는 보편적인 성질을 넣고, 파생 클래스는 해당 객체만이 가지는
특수한 성질이나 구체적인 동작을 넣는다.
// 따라서 더 큰 범위의 개념을 가지는 것이 기본 클래스, 그 아래의 구체적인 개념을 가지는 파생 클래스가 된다.
// 3) 파생클래스 객체가 생성될 때 생성자와 소멸자의 실행순서를 설명하라
// 먼저 생성자는 부모 먼저, 그다음 자식 순서로 실행되고 소멸자는 자식 먼저, 그다음 부모 순서로 실행된다.
// 4) 다운캐스팅과 업캐스팅을 설명하시오
// 업캐스팅은 자식 클래스의 객체를 부모 클래스의 포인터로 가리키는 것이다. 이 경우 자식 클래스의 객체는 부모
클래스를 포함하기 때문에 오류가 발생할 일이 없어 안전하기 때문에 별도의 형변환 연산자 없이 자동으로 지원한다.
다운캐스팅 다운캐스팅은 업캐스팅된 부모 포인터가 가리키는 객체를 다시 원래의 자식 클래스 포인터로 되돌리는 것이다.
// 그러나 부모 포인터가 가리키는 실제 객체가 반드시 자식 클래스라는 보장이 없고, 실제로는 부모 객체인데 억지로
자식으로 변환해 자식만의 멤버에 접근하려 하면 메모리 오류가 발생할 수 있다.
// 따라서 개발자가 이를 확인하고 책임진다는 의미로 반드시 명시적인 형변환을 해줘야 한다.
// 5) 업캐스팅을 허용한 이유를 설명하라.
// 부모클래스는 1개이지만 자식 클래스는 수없이 많을 수 있음, 모든 포인터를 저장할 수 있도록 void 포인터를 만든
이유와 비슷하니 생각해볼 것
// 업캐스팅을 사용하면 부모 클래스 포인터 하나만으로 모든 자식 객체들을 다룰 수 있다.
// 마치 void* 가 어떤 타입의 주소든 다 저장할 수 있는 것과 같이, 부모 포인터는 다양한 자식들의 타입과 상관없이
// 공통된 부모의 포인터로 한꺼번에 관리할 수 있게 된다.
|
|
