Post

[C++] 명품 C++ 프로그래밍 9장 실습문제 풀이

9장 가상함수와 추상 클래스


1번

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <string>
using namespace std;

class Converter {
protected:
    double ratio;
    virtual double convert(double src) = 0;
    virtual string getSourceString() = 0;
    virtual string getDestString() = 0;
public:
    Converter(double ratio) { this->ratio = ratio; }
    void run() {
        double src;
        cout << getSourceString() << "을 " << getDestString() << "로 바꿉니다.";
        cout << getSourceString() << "을 입력하세요 >> ";
        cin >> src;
        cout << "변환 결과 : " << convert(src) << getDestString() << endl;
    }
};

class WonToDollar : public Converter {
public:
    WonToDollar(double ratio)
        : Converter(ratio) { }
    virtual double convert(double src) { return src / ratio; }
    virtual string getSourceString() { return "원"; }
    virtual string getDestString() { return "달러"; }
};

int main() {
    WonToDollar wd(1010);
    wd.run();
}

2번

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <string>
using namespace std;

class Converter {
protected:
    double ratio;
    virtual double convert(double src) = 0;
    virtual string getSourceString() = 0;
    virtual string getDestString() = 0;
public:
    Converter(double ratio) { this->ratio = ratio; }
    void run() {
        double src;
        cout << getSourceString() << "을 " << getDestString() << "로 바꿉니다.";
        cout << getSourceString() << "을 입력하세요 >> ";
        cin >> src;
        cout << "변환 결과 : " << convert(src) << getDestString() << endl;
    }
};

class KmToMile : public Converter {
public:
    KmToMile(double ratio)
        : Converter(ratio) { }
    virtual double convert(double src) { return src / ratio; }
    virtual string getSourceString() { return "Km"; }
    virtual string getDestString() { return "Mile"; }
};

int main() {
    KmToMile toMile(1.609344);
    toMile.run();
}

3번

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <string>
using namespace std;

class LoopAdder {
    string name;
    int x, y, sum;
    void read();
    void write();
protected:
    LoopAdder(string name = "") { this->name = name; }
    int getX() { return x; }
    int getY() { return y; }
    virtual int calculate() = 0;
public:
    void run();
};

void LoopAdder::read() {
    cout << name << ':' << endl;
    cout << "처음 수에서 두 번째 수까지 더합니다. 두 수를 입력하세요 >> ";
    cin >> x >> y;
}
void LoopAdder::write() {
    cout << x << "에서 " << y << "까지의 합 = " << sum << "입니다." << endl;
}
void LoopAdder::run() {
    read();
    sum = calculate();
    write();
}

class ForLoopAdder : public LoopAdder {
public:
    ForLoopAdder(string name)
        : LoopAdder(name) { }
    virtual int calculate() {
        int sum = 0;
        for (int i = getX(); i <= getY(); i++)
            sum += i;
        return sum;
    }
};

int main() {
    ForLoopAdder forLoop("For Loop");
    forLoop.run();
}

4번

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <iostream>
#include <string>
using namespace std;

class LoopAdder {
    string name;
    int x, y, sum;
    void read();
    void write();
protected:
    LoopAdder(string name = "") { this->name = name; }
    int getX() { return x; }
    int getY() { return y; }
    virtual int calculate() = 0;
public:
    void run();
};

void LoopAdder::read() {
    cout << name << ':' << endl;
    cout << "처음 수에서 두 번째 수까지 더합니다. 두 수를 입력하세요 >> ";
    cin >> x >> y;
}
void LoopAdder::write() {
    cout << x << "에서 " << y << "까지의 합 = " << sum << "입니다." << endl;
}
void LoopAdder::run() {
    read();
    sum = calculate();
    write();
}

class WhileLoopAdder : public LoopAdder {
public:
    WhileLoopAdder(string name)
        : LoopAdder(name) { }
    virtual int calculate() {
        int i = getX(), sum = 0;
        while (i <= getY()) {
            sum += i;
            i++;
        }
        return sum;
    }
};

class DoWhileLoopAdder : public LoopAdder {
public:
    DoWhileLoopAdder(string name)
        : LoopAdder(name) { }
    virtual int calculate() {
        int i = getX(), sum = 0;
        do {
            sum += i;
            i++;
        } while (i <= getY());
        return sum;
    }
};
int main() {
    WhileLoopAdder whileLoop("While Loop");
    DoWhileLoopAdder doWhileLoop("Do While Loop");

    whileLoop.run();
    doWhileLoop.run();
}

5번

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
using namespace std;

class AbstractGate{
protected:
    bool x,y;
public:
    void set(bool x, bool y){ this->x = x; this->y = y;}
    virtual bool operation() = 0;
};

class ANDGate : public AbstractGate{
    public:
        virtual bool operation(){
            if(x == true && y == true)
                return true;
            else 
                return false;
        }
};
class ORGate : public AbstractGate{
    public:
        virtual bool operation(){
            if(x == true || y == true)
                return true;
            else 
                return false;
        }
};
class XORGate : public AbstractGate {
    public:
        virtual bool operation(){
            if(x != y)
                return true;
            else 
                return false;
        }
};

int main(){
    ANDGate andGate;
    ORGate orGate;
    XORGate xorGate;

    andGate.set(true,false);
    orGate.set(true,false);
    xorGate.set(true,false);
    cout.setf(ios::boolalpha);
    cout<<andGate.operation()<<endl;
    cout<<orGate.operation()<<endl;
    cout<<xorGate.operation()<<endl;
}

6번

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream>
using namespace std;

class AbstractStack {
public:
    virtual bool push(int n) = 0;
    virtual bool pop(int& n) = 0;
    virtual int size() = 0;
};

class IntStack : AbstractStack{
    int* stack;
    int top, capacity;
public:
    IntStack(int capacity = 100) {
        this->capacity = capacity;
        stack = new int[capacity];
        top = -1;
    }
    ~IntStack() { if (stack) delete[]stack; }
    virtual bool push(int n) {
        if (top == capacity - 1) {
            cout << "Stack is Full" << endl;
            return false;
        }
        else {
            stack[++top] = n;
            return true;
        }
    }
    virtual bool pop(int& n) {
        if (top == -1) {
            cout << "Stack is Empty" << endl;
            return false; 
        }
        else{
            n = stack[top--];
            return true;
        }
    }
    virtual int size() { return top + 1; }
};

int main() {
    IntStack IS(100);
    int n;
    cout << "스택에 삽입할 5개의 정수를 입력하라>> ";
    for (int i = 0; i < 5; i++) {
        cin >> n;
        IS.push(n);
    }

    cout << "스택의 크기 : " << IS.size() << endl;
    cout << "스택의 원소를 순서대로 제거하여 출력한다 >> ";
    while (IS.size() != 0) {
        IS.pop(n);
        cout << n << ' ';
    }
    cout << endl << "스택의 현재 크기 : " << IS.size() << endl;

}

7번

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <string>
using namespace std;

class Shape {
protected:
    string name;
    int width, height;
public:
    Shape(string n = "", int w = 0, int h = 0) {
        name = n;
        width = w;
        height = h;
    }
    virtual double getArea() { return 0; }
    string getName() { return name; }
};

class Oval : public Shape {
public:
    Oval(string name, int width, int height)
        :Shape(name, width, height) { }
    virtual double getArea() { return width * height * 3.14; }
};
class Rect : public Shape {
public:
    Rect(string name, int width, int height)
        :Shape(name, width, height) { }
    virtual double getArea() { return width * height; }
};
class Triangular : public Shape {
public:
    Triangular(string name, int width, int height)
        :Shape(name, width, height) { }
    virtual double getArea() { return width * height / 2; }
};

int main() {
    Shape* p[3];
    p[0] = new Oval("빈대떡", 10, 20);
    p[1] = new Rect("찰떡", 30, 40);
    p[2] = new Triangular("토스트", 30, 40);

    for (int i = 0; i < 3; i++)
        cout << p[i]->getName() << " 넓이는 " << p[i]->getArea() << endl;
    for (int i = 0; i < 3; i++)
        delete p[i];
}

8번

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <string>
using namespace std;

class Shape {
protected:
    string name;
    int width, height;
public:
    Shape(string n = "", int w = 0, int h = 0) {
        name = n;
        width = w;
        height = h;
    }
    virtual double getArea() = 0;
    string getName() { return name; }
};

class Oval : public Shape {
public:
    Oval(string name, int width, int height)
        :Shape(name, width, height) { }
    virtual double getArea() { return width * height * 3.14; }
};
class Rect : public Shape {
public:
    Rect(string name, int width, int height)
        :Shape(name, width, height) { }
    virtual double getArea() { return width * height; }
};
class Triangular : public Shape {
public:
    Triangular(string name, int width, int height)
        :Shape(name, width, height) { }
    virtual double getArea() { return width * height / 2; }
};

int main() {
    Shape* p[3];
    p[0] = new Oval("빈대떡", 10, 20);
    p[1] = new Rect("찰떡", 30, 40);
    p[2] = new Triangular("토스트", 30, 40);

    for (int i = 0; i < 3; i++)
        cout << p[i]->getName() << " 넓이는 " << p[i]->getArea() << endl;
    for (int i = 0; i < 3; i++)
        delete p[i];
}

9번

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <iostream>
#include <string>
using namespace std;

class Printer {
    string model, manufacturer;
    int printedCount, availableCount;
public:
    Printer(string model, string manufacturer, int availableCount) {
        this->model = model;
        this->manufacturer = manufacturer;
        this->availableCount = availableCount;
    }
    virtual ~Printer(){}
    bool isAvailToPrint(int count) {
        if (availableCount < count) {
            cout << "용지가 부족하여 프린트할 수 없습니다" << endl;
            return false;
        }
        else
            return true;
    }
    virtual void print(int count) {
        availableCount -= count;
        printedCount += count;
    }
    virtual void show() {
        cout << model << ", " << manufacturer << ", 남은종이 " << availableCount << "장, ";
    }
};

class InkJetPrinter : public Printer {
    int availableInk;
public:
    InkJetPrinter(string model, string manufacturer, int availableCount, int availableInk)
        : Printer(model, manufacturer, availableCount) {
        this->availableInk = availableInk;
    }
    virtual ~InkJetPrinter(){}
    virtual void print(int count) {
        if (availableInk < count) {
            cout << "잉크가 부족하여 프린트할 수 없습니다." << endl;
            return;
        }
        if (Printer::isAvailToPrint(count)) {
            Printer::print(count);
            availableInk -= count;
            cout << "프린트하였습니다." << endl;
        }
    }
    virtual void show() {
        cout << "잉크젯 : ";
        Printer::show();
        cout << "남은 잉크 " << availableInk << endl;
    }
};

class LaserPrinter : public Printer {
    int availableTonner;
public:
    LaserPrinter(string model, string manufacturer, int availableCount, int availableTonner)
        : Printer(model, manufacturer, availableCount) {
        this->availableTonner = availableTonner;
    }
    virtual ~LaserPrinter(){}
    virtual void print(int count) {
        if (availableTonner < count) {
            cout << "토너가 부족하여 프린트할 수 없습니다." << endl;
            return;
        }
        if (Printer::isAvailToPrint(count)) {
            Printer::print(count);
            availableTonner -= count;
            cout << "프린트하였습니다." << endl;
        }
    }
    virtual void show() {
        cout << "레이저 : ";
        Printer::show();
        cout << "남은 토너 " << availableTonner << endl;
    }
};

class PrinterManager {
    Printer* printers[2];
    int printerCount = 2;
public:
    ~PrinterManager(){
        for(int i = 0 ; i < printerCount ; i++)
            if(printers[i]) delete printers[i]; 
    }
    void run() {
        printers[0] = new InkJetPrinter("Officejet V40", "HP", 5, 10);
        printers[1] = new LaserPrinter("SCX-6x45", "삼성전자", 3, 20);

        cout << "현재 작동중인 2대의 프린터는 아래와 같다" << endl;

        for (int i = 0; i < printerCount; i++)
            printers[i]->show();

        int selectPrinter, printCount;
        char cont;
        while (true) {
            cout << endl;
            cout << "프린터(1:잉크젯, 2:레이저)와 매수 입력 >> ";
            cin >> selectPrinter >> printCount;
            switch (selectPrinter) {
            case 1:
                printers[0]->print(printCount);
                break;
            case 2:
                printers[1]->print(printCount);
                break;
            }

            for (int i = 0; i < printerCount; i++)
                printers[i]->show();

            cout << "계속 프린트 하시겠습니까?(y/n) >> ";
            cin >> cont;
            if (cont == 'n')
                break;
        }
    }
};
int main() {
    PrinterManager PM;
    PM.run();
}

10번

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include <iostream>
#include <string>
using namespace std;

class Shape {
    Shape* next;
public:
    Shape* getNext() { return next; }
    virtual ~Shape(){}
    void setNext(Shape* next) { this->next = next; }
    virtual void show() = 0;
};

class Line : public Shape {
    string name = "Line";
public:
    virtual ~Line(){}
    virtual void show() { cout << name << endl; }
};
class Circle : public Shape {
    string name = "Circle";
public:
    virtual ~Circle(){}
    virtual void show() { cout << name << endl; }
};
class Rectangle : public Shape {
    string name = "Rectangle";
public:
    virtual ~Rectangle(){}
    virtual void show() { cout << name << endl; }
};

class ClassUI {
public:
    static int getMenu() {
        int selectMenu;
        cout << "삽입:1, 삭제:2, 모두보기:3, 종료:4 >> ";
        cin >> selectMenu;
        return selectMenu;
    }
    static int getShape() {
        int selectShape;
        cout << "선:1, 원:2, 사각형:3 >> ";
        cin >> selectShape;
        return selectShape;
    }
    static int getIndex() {
        int selectIndex;
        cout << "삭제하고자 하는 도형의 인덱스 >> ";
        cin >> selectIndex;
        return selectIndex;
    }
};

class GraphicEditor {
    Shape* pStart, * pLast;
    void insert() {
        Shape* tmp = NULL;
        switch (ClassUI::getShape()) {
            case 1:
                tmp = new Line(); break;
            case 2:
                tmp = new Circle(); break;
            case 3:
                tmp = new Rectangle(); break;
        }
        tmp->setNext(NULL);
        if (pStart == NULL)
            pStart = pLast = tmp;
        else {
            pLast->setNext(tmp);
            pLast = tmp;
        }
    }
    void remove() {
        Shape* curShape = pStart;
        Shape* prevShape = NULL;
        Shape* rShape = NULL;
        int rIndex = ClassUI::getIndex();
        int count = 0;

        while (rIndex != count) {
            prevShape = curShape;
            curShape = curShape->getNext();
            count++;
        }

        if (curShape == NULL) { // pStart == NULL
            cout << "Empty!" << endl;
            return;
        }
        else if (prevShape == NULL) { // rShape == pStart
            rShape = curShape;
            pStart = pStart->getNext();
        }
        else if (curShape->getNext() == NULL) { // rShape == pLast
            rShape = curShape;
            prevShape->setNext(NULL);
            pLast = prevShape;
        }
        else { // default
            rShape = curShape;
            prevShape->setNext(curShape->getNext());
        }

        if (pStart == NULL)
            pStart = pLast = NULL;
        delete rShape;
    }
    void showAll() {
        int i = 0;
        Shape* curShape = pStart;
        while (curShape != NULL) {
            cout << i++ << ": ";
            curShape->show();
            curShape = curShape->getNext();
        }
    }
public:
    GraphicEditor() { pStart = pLast = NULL; }
    ~GraphicEditor() {
        Shape * curShape = pStart;
        Shape * rShape = NULL;
        while(curShape != NULL){
            rShape = curShape;
            curShape = curShape->getNext();
            delete rShape;
        }
    }
    void run() {
        cout << "그래픽 에디터입니다." << endl;
        int flag = true;
        while (flag) {
            switch (ClassUI::getMenu()) {
            case 1:
                insert();
                break;
            case 2:
                remove();
                break;
            case 3:
                showAll();
                break;
            case 4:
                flag = false;
                break;
            default:
                cout << "다시 입력하세요" << endl;
                break;
            }
        }
    }
};

int main() {
    GraphicEditor GE;
    GE.run();
}
This post is licensed under CC BY 4.0 by the author.