ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 명품 C++ 10장 16번
    C++ 2018. 11. 17. 05:19

    16. vector<Shape*> v;를 이용하여 간단한 그래픽 편집기를 콘솔 바탕으로 만들어보자. Shape과 Circle, Line, Rect 클래스는 다음과 같다. 생성된 도형객체를 v에 삽입하고 관리하라. 9장 실습 문제 10번의 힌트를 참고하라.


    Shape.h


    #ifndef SHAPE_H
    #define SHAPE_H
    class Shape {
    protected:
        virtual void draw() = 0;
    public:
        void paint();
    };
    #endif


    Shape.cpp


    #include <iostream>
    #include "Shape.h"
    using namespace std;
    void Shape::paint() {
        draw();
    }


    Circle.h


    class Circle : public Shape {
    protected:
        virtual void draw();
    };


    Circle.cpp


    #include <iostream>
    using namespace std;
    #include "Shape.h"
    #include "Circle.h"
    void Circle::draw() {
        cout << "Circle" << endl;
    }


    Rect.h


    class Rect : public Shape {
    protected:
        virtual void draw();
    };


    Rect.cpp


    #include <iostream>
    using namespace std;
    #include "Shape.h"
    #include "Rect.h"
    void Rect::draw() {
        cout << "Rectangle" << endl;
    }


    Line.h


    class Line : public Shape {
    protected:
        virtual void draw();
    };


    Line.cpp


    #include <iostream>
    using namespace std;
    #include "Shape.h"
    #include "Line.h"
    void Line::draw() {
        cout << "Line" << endl;
    }


    main.cpp


    #include <iostream>
    #include <string>
    #include "Shape.h"
    #include "Circle.h"
    #include "Rect.h"
    #include "Line.h"
    #include <vector>
    using namespace std;
    class UI { // 화면 출력 및 키 입력 함수
        static int n; // 무슨 기능을 할지 입력 받은 숫자
    public:
        static void start(); // 첫줄에 나오는 그래픽 에디터 입니다 출력
        static int menu(); // 삽입 삭제 모두보기 종료
        static int insert(); // 도형 삽입
        static int del(); // 도형 삭제
    };
    int UI::n = 0;
    void UI::start() {
        cout << "그래픽 에디터입니다." << endl;
    }
    int UI::menu() { // 메뉴 출력 및 입력
        cout << "삽입:1, 삭제:2, 모두보기:3, 종료:4 >> ";
        cin >> n;
        return n;
    }
    int UI::insert() { // 도형 삽입에 대한 메뉴 출력 및 입력
        cout << "선:1, 원:2, 사각형:3 >> ";
        cin >> n;
        return n;
    }
    int UI::del() { // 도형 삭제에 대한 메뉴 출력 및 입력
        cout << "삭제하고자 하는 도형의 인덱스 >> ";
        cin >> n;
        return n;
    }
    class GraphicEditor {
        vector<Shape*> v;
        vector<Shape*>::iterator it;
    public:
        GraphicEditor() {}
        void insert() {
            int n = UI::insert();
            if (n == 1) // 라인
                v.push_back(new Line());
            else if (n == 2) // 원
                v.push_back(new Circle());
            else if (n == 3) // 사각형
                v.push_back(new Rect());
            else cout << "입력 에러" << endl;
        }
        void deleteShape() {
            int n = UI::del();
            Shape* del;
            it = v.begin();
            for (int i = 0; i < n; ++i)
                ++it;
            del = *it;
            it = v.erase(it);
            delete del;
        }
        void showAll() {
            for (int i = 0; i < v.size(); ++i) {
                cout << i << ": ";
                v[i]->paint();
            }
        }
        void start() {
            UI::start();
            for (;;) {
                int m = UI::menu();
                if (m == 1) // 삽입
                    insert();
                else if (m == 2) // 삭제
                    deleteShape();
                else if (m == 3) // 전체 보기
                    showAll();
                else if (m == 4) break;
                else cout << "입력 에러 " << endl;
            }
        }
    };
    int main() {
        GraphicEditor* g=new GraphicEditor;
        g->start();
        delete g;
    }


    실행결과



    vector의 원소를 삭제하려면 벡터에 들어 있는 원소를 개별적으로 삭제하는 멤버 함수로 erase()가 있지만 erase()는 iterator와 함께 사용해야 합니다.


    vector<Shape*>::iterator it;
    Shape* del;
    it = v.begin();
    for (int i = 0; i < n; ++i)
    ++it;
    del = *it;
    it = v.erase(it);
    delete del;


    삭제하는 코드에서 설명하자면, it는 처음에 벡터의 처음 원소를 가리키고, 원하는 위치까지 증가시키면서 v[n]에 있는 원소를 가리킵니다.

    그 이후, erase(it)가 it가 가리키는 원소를 삭제한 후, 벡터의 원소들을 다시 앞으로 한 자리씩 이동시킵니다. 그리고 삭제된 다음 원소를 가리키는 포인터를 리턴합니다. 그러므로 erase(it) 후에는 다음과 같이 반드시 it가 리턴 값으로 치환되어야 합니다.

    'C++' 카테고리의 다른 글

    명품 C++ 10장 Open Challenge  (0) 2018.11.17
    명품 C++ 10장 15번  (0) 2018.11.17
    명품 C++ 10장 14번  (0) 2018.11.17
    명품 C++ 10장 13번  (0) 2018.11.17
    명품 C++ 10장 12번  (0) 2018.11.17

    댓글

© 2018 TISTORY. All rights reserved.