-
명품 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_Hclass Shape {protected:virtual void draw() = 0;public:void paint();};#endifShape.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