3장. Rectangle 응용 프로그램
Day 9(강의):
상속과 포함 관계
사각형 클래스
상속과 포함 관계
상속을 통한 코드의 재사용
이즈-어(is-a) 관계
UML(Unified Modeling Language) 표기법과 이 책의 표기법
(상속받은 멤버는 필요한 경우를 제외하고 표기하지 않음)
application
penApplication
application
penApplication application
mouseDown paint run
virtual okBox
mouseDown paint pen-
Application timer- Interval
pen- Application
포함을 통한 코드의 재사용
해즈-어(has-a) 관계
wout 객체 멤버(점선 표시) -> 윈도우 출력 전담 부품 소유 window 클래스 해즈-어 wostream 클래스
wostrem 클래스의 << 연산자 멤버 함수(보충 문법절)
window
window line
virtual run virtual
mouseDown virtual paint clientX clientY wout
- - -
line
window line
virtual run virtual
mouseDown virtual paint clientX clientY wout- - -
line theWindow
wostream wostream
width width
<< <<
<<
fieldWidth floatPrecision winPtr
- - -
wostream width width
<< <<
<<
fieldWidth floatPrecision winPtr
- - -
UML 표기법과 이 책의 표기법
복합 객체
완성된 클래스의 객체를 객체 멤버로 소유하는 객체
비디오 플레이어 -> 모터, 시계 등과 같은 부속품을 소유하는 복합 객체 포함 관계는 여러 레벨에 걸쳐 이뤄짐
비디오 플레이어 -> 다시 홈 시어터 시스템의 부속품
window wostream
window
window line
virtual run virtual
mouseDown virtual paint clientX clientY wout
- - -
line
wostream wostream
width width
<< <<
<<
fieldWidth floatPrecision winPtr
- - -
Rectangle 응용 프로그램
상속과 포함을 통한 pclaf(클래스 라이브러리)의 사용
window
application
rectangleApplication window line
virtual run virtual
mouseDown virtual paint
application
mouseDown paint run
virtual okBox
mouseDown paint rectangle- Application
clientX clientY wout- - -
timer- Interval
childWindow
wostream
menu
+ mainLAF
PC Little Application Framework (pclaf.h, pclaf.cpp)
rectangleApp.cpp
line
run
childWindow
mouseDown paint timer
rectangle- Application
rect
includes
move- To rect
+ draw upperLeftXupperLeftYlowerRightX lowerRightY
theRectangle 0
상속을 통한 재사용
포함(wout) 후 상속을 통한 재사용 상속을 통한
재사용
새롭게 정의 해 사용
Rectangle 응용 프로그램의 작성 과정
개발개발 개발사용
개발수정 조립식 제작
pclaf
부품 변형 (상속 후 mouseDown, paint 재정의)
Rectangle 응용 프로그램
부품 추가 (사각형 클래스)
창 있는 집 만들기
pclaf의 문 달린 집을 상속 -> 문고리 달기 -> 창 제작 -> 창 달기 Rectangle 응용 프로그램 작성
pclaf의 application 클래스를 상속 -> rectangleApplication의 mouseDown과 paint 멤버 함수의 재정의 -> rect 클래스의 정의 -> rect 클래스의 객체 사용
카세트 플레이어 제작
기본 플레이어를 상속 -> 재생, 앞으로 빨리 감기 버튼에 기능 연계 -> 부속품 제작 -> 부속품 적용
사각형 클래스
사각형의 표현(모델링)
=> rect 클래스(모델링은 클래스 레벨의 작업)
멤버 변수
a. (upperLeftX, upperLeftY) + (lowerRightX, lowerRightY) -> 선택!
b. (upperLeftX, upperLeftY) + width + height
이외 lineColor, lineWidth, backGroundColor, … 추가 가능
(upperLeftX, upperLeftY) (lowerRightX, upperLeftY)
(lowerRightX, lowerRightY) (upperLeftX, lowerRightY)
x y
width
height
멤버 함수
① draw: 스스로 자기 자신을 클라이언트 영역에 그림
-> 그리기 위해 line, setPen 등의 멤버 함수들에 접근할 수 있어야 함
-> line, setPen 등은 rectangleApplication 클래스의 객체인 theApp가 window 클 래스로부터 상속받아 소유
-> theApp 객체(윈도우 객체)를 파라미터로 받아야 함(주소 전달 방식) -> void draw(window *); 또는 void draw(window &);
void draw(window *)인 경우 – 객체 포인터 사용
mouseDown paint rectangle- Application rectangle- Application
includes
move- To rect
draw upperLeftX 30 upperLeftY 30 lowerRightX 100 lowerRightY 80
rectangleApplication
mouseDown paint rectangle- Application rectangle- Application
rect
includes
move- To rect
draw upperLeftXupperLeftY lowerRightX lowerRightY
void draw (window * theWindow) {
theWindow->setPen(…);
theWindow->line(…)
… }
theApp &theApp theRect
theRect.draw(&theApp);
void draw(window &)인 경우 – 객체 레퍼런스 사용
mouseDown paint rectangle- Application rectangle- Application
includes
move- To rect
draw upperLeftX 30 upperLeftY 30 lowerRightX 100 lowerRightY 80
rectangleApplication
mouseDown paint rectangle- Application rectangle- Application
rect
includes
move- To rect
draw upperLeftXupperLeftY lowerRightX lowerRightY
void draw (window & theWindow) {
theWindow.setPen(…);
theWindow.line(…)
… }
theApp theRect
theRect.draw(theApp);
별명
void draw(window)인 경우 – 값 전달 호출
덩치 큰 윈도우 객체의 복사본 객체 사용 -> 성능 저하, 메모리 낭비
mouseDown paint rectangle- Application rectangle- Application
includes
move- To rect
draw upperLeftX 30 upperLeftY 30 lowerRightX 100 lowerRightY 80
rectangleApplication
mouseDown paint rectangle- Application rectangle- Application
rect
includes
move- To rect
draw upperLeftXupperLeftY lowerRightX lowerRightY
void draw (window theWindow) {
theWindow.setPen(…);
theWindow.line(…)
… }
mouseDown paint rectangle- Application rectangle- Application
theRect
theRect.draw(theApp);
theApp
② moveTo: 스스로 자기 자신을 주어진 위치로 이동 -> void moveTo(int,int,int,int);
-> 크기가 고정된 사각형인 경우 void moveTo(int,int);도 가능
③ includes: 마우스 클릭점이 자신의 내부점인지 판단 -> int includes(int,int); 또는 bool includes(int,int);
④ rect: 생성자 함수
-> rect(int,int,int,int);
이외 area, changeLineColor, increment, lager, … 추가 가능(보충 문법절)
rect 클래스의 인터페이스 정의
멤버 변수 -> 예제 코드 길이를 줄이기 위해 pulic 가시성 부여 -> 보충 문법절에서 개선
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17
// RECTANGLE CLASS class rect {
public:
// constructor rect(int,int,int,int);
// operations
void moveTo(int,int,int,int);
int includes(int,int);
void draw(window *);
// data fields int upperLeftX;
int upperLeftY;
int lowerRightX;
int lowerRightY;
};
rect 클래스의 구현
생성자 함수의 초기자(initializer)
01 0203 0405 06 0708 0910 11 1213 1415
rect::rect(int a, int b, int c, int d) {upperLeftX = a;
upperLeftY = b;
lowerRightX = c;
lowerRightY = d;
}
void rect::moveTo(int a, int b, int c, int d) {
upperLeftX = a;
upperLeftY = b;
lowerRightX = c;
lowerRightY = d;
}
0102 0304 05
rect::rect(int a, int b, int c, int d)
: upperLeftX(a), upperLeftY(b), lowerRightX(c), lowerRightY(d) {// no action
}
상수 파라미터
int includes(const int, const int); // rect 클래스 인터페이스 정의에서 int rect::includes(const int x, const int y) // 멤버 함수의 구현에서
0102 0304 0506 0708 0910 1112 13 1415 1617 18 1920
void rect::draw(window * theWindow) {// first make sure the pen is correct
theWindow->setPen(blue, solidLine, 1);
// then draw the lines
theWindow->line(upperLeftX, upperLeftY, lowerRightX, upperLeftY);
theWindow->line(upperLeftX, upperLeftY, upperLeftX, lowerRightY);
theWindow->line(upperLeftX, lowerRightY, lowerRightX, lowerRightY);
theWindow->line(lowerRightX, upperLeftY, lowerRightX, lowerRightY);
}
int rect::includes(int x, int y)
{if((upperLeftX<x) && (lowerRightX>x)) if((upperLeftY<y) && (lowerRightY>y))
return 1;
return 0;
}
Day 10(실습):
Rectangle 응용 프로그램 실습
Rectangle 응용 프로그램 실습
실습 과제
0102 0304 0506 07 0809 1011 1213 1415 16 1718 1920 21 2223 2425
rect * theRectangle = 0;
void rectangleApplication::mouseDown(int x, int y) {if(theRectangle != 0) {
if(theRectangle->includes(x,y)) { // remove the old rectangle delete theRectangle;
// create a new one
theRectangle = new rect(x, y, x+70, y+50);
}}
elsetheRectangle = new rect(x, y, x+70, y+50);
// then update the screen update();
}
void rectangleApplication::paint() {if(theRectangle != 0)
theRectangle->draw(this);
}
15번째 줄의 theRectangle = new rect(x, y, x+70, y+50);
객체의 동적 생성
includes
move- To rect
draw upperLeftX 30 upperLeftY 30 lowerRightX 100 lowerRightY 80
rect
includes
move- To rect
draw upperLeftXupperLeftY lowerRightX lowerRightY
xx
xx
② rect::rect ①
③ theRectangle
this 시스템 변수(자기 참조 포인터)
항상 현재 실행되는 멤버 함수를 소유한 객체를 포인팅
현재 실행되는 멤버 함수는 paint -> paint를 소유하는 객체는 theApp -> this는 theApp 객체를 포인팅
theRectangle->draw(this); = theRectangle->draw(&theApp);(24번째 줄) update(); = (this->)update();(18번째 줄)
생략 가능
mouseDown paint rectangle- Application rectangle- Application
includes
move- To rect
draw upperLeftX 30 upperLeftY 30 lowerRightX 100 lowerRightY 80
rectangleApplication
mouseDown paint rectangle- Application rectangle- Application
rect
includes
move- To rect
draw upperLeftXupperLeftY lowerRightX lowerRightY
void draw (window * theWindow) {
theWindow->setPen(…);
theWindow->line(…)
… }
theApp &theApp theRect
theRect.draw(&theApp);
this
&theApp
Rectangle 응용 프로그램의 동작 과정
window
application
rectangleApplication
mouse- Down
paint rectangle-
Application
rectangle- Application theApp
①rectangleApplication theApp
(“RECTANGLES”)
②rectangleApplication (“RECTANGLES”)
③theApp.run()
표시
윈도우 메시지 루프
④
⑤
실행
⑥mouseDown (30,30)
⑨update()
⑪paint()
⑭⑮line
&theApp this
includes
move- To rect
draw
upperLeftX 30 upperLeftY 30 lowerRightX 100 lowerRightY 80
rect
⑦theRectangle=
new rect(30,30,30+70,30+50) theRectanble
⑫theRectangle->
draw(this)
⑬setPen
(blue,solidLine,1)
⑧rect::rect(30,30,100,80)
③application::run()
⑨window::update()
⑩클라이언트 영역 업데이트 요청
⑬window::setPen(blue,solidLine,1)
Day 11(실습):
응용 과제 2번 실습
응용 과제 2번 실습
클라이언트 영역을 다시 그려야 하는 상황
윈도우 운영체제 감지 -> paint 멤버 함수 호출
크기 조정
크기 조정
최대화, 최소화
뒤로 보내기
앞으로 가져오기
생성된 사각형들의 보존
객체 포인터 배열
const int MAXRECTS = 20;
rect * rects[MAXRECTS] = {0};
0 1 2 3 4 5 19 rects
includes move- To rect
draw 30
30 100 80
includes move- To rect
draw 40
40 110 90
includes move- To rect
draw 50
60 150 110
0 0 0 0
0102 03 0405 0607 08 0910 1112 13
void rectangleApplication::mouseDown(int x, int y) {
int i;
for(i=0; rects[i]!=0; i++) // 삽입할 배열 내 위치 찾기 {};
if(i == 0)
rects[i] = new rect(x, y, x+70, y+50);
else
if(rects[i-1]->includes(x,y)) // i-1이 삽입할 위치 rects[i] = new rect(x, y, x+70, y+50);
update();
}
생성된 사각형들의 그림 유지
객체 포인터 배열 내의 모든 사각형들을 다시 그림 01
0203 04 05
void rectangleApplication::paint() {for(int i=0; rects[i]!=0; i++)
rects[i]->draw(this);
}