Development of Fashion CAD Systemfashiontech.snu.ac.kr/note/fashioncad/11-More on...

Post on 20-Jul-2020

3 views 0 download

Transcript of Development of Fashion CAD Systemfashiontech.snu.ac.kr/note/fashioncad/11-More on...

Sungmin Kim

SEOUL NATIONAL UNIVERSITY

Development of Fashion CAD System

11. More on Class

Introduction Topics File System

ASCII

– FILE Pointer

Binary

– TFileStream Class

More on Class

Access Specifier (접근 지정자)

Operator Overloading (연산자 오버로딩)

Inheritance (상속)

– 상속에 의한 TFileStream 의 확장

2

File System File I/O UI 구성 TMainForm 에 Menu 추가

Dialog Box 추가

3

TOpenDialog TSaveDialog

File System File I/O UI 구성 Dialog Box 속성 설정

공통 설정

TOpenDIalog

– Name=OpenDialog, Title=Load Project

TSaveDialog

– Name= SaveDialog, Title=Save Project

4

File System File I/O UI 구성 File-Save Project 메뉴

5

void __fastcall TMainForm::SaveProject1Click(TObject *Sender){TChildForm *C=(TChildForm*)ActiveMDIChild;if (C){

SaveDialog->FileName="";if (SaveDialog->Execute()){

C->Garment->SaveToFile(SaveDialog->FileName);}

}}

File System File I/O UI 구성 File-Load Project 메뉴

TMainForm

TChildForm

6

void __fastcall TMainForm::LoadProject1Click(TObject *Sender){LoadDialog->FileName="";if (LoadDialog->Execute()){

new TChildForm(Application,LoadDialog->FileName,1);}

}

void __fastcall TMainForm::NewWindow1Click(TObject *Sender){new TChildForm(Application,"NewProject-"+AnsiString(MDIChildCount+1)+".Pattern",0);}

새 프로젝트/기존 프로젝트 구분 flag

__fastcall TChildForm::TChildForm(TComponent* Owner,AnsiString C,int Type): TForm(Owner){Caption=C;NewCanvas=new ptNewCanvas;Garment=new ptGarment;if (Type==1){

Garment->LoadFromFile(C);}

}

File System Save to File File의 종류

ASCII (Text) File

– 보통 사람이 이해할 수 있는 text 로 파일을 저장

– 용량이 크고 로딩 시간이 길지만 직관적 이해 및 부분적 수정이 가능함

– 소량의 단순한 데이터 저장에 사용

Binary File

– 보통 사람이 이해할 수 없는 2진수로 파일을 저장

– 용량이 작고 로딩 시간이 짧지만 이해 및 부분 수정이 불가능

– 사진, 음악 등 멀티 미디어 데이터 혹은 대용량 데이터 저장에 사용

File 저장 방법

File Pointer 생성

데이터 쓰기

File Pointer 닫기

7

File System Save to File ptGarment::SaveToFile 함수의 작성

Procedural parametric design 이므로 Step 만 저장하면 됨

– FILE pointer 를 쓰기 위해 ptGarment.h 함수에서 <stdio.h> 를 include 해야 함

8

void ptGarment::SaveToFile(AnsiString N){FILE *F=fopen(N.c_str(),"w+");fprintf(F,"Version=1\n"); // 20160624int i;fprintf(F,"Step=%d\n",StepNum);for(i=0;i<StepNum;i++){

Step[i]->SaveToFile(F);}

fclose(F);}

File System Save to File ptDesignStep::SaveToFile 함수의 작성

9

void ptDesignStep::SaveToFile(FILE *F){fprintf(F,"Version=1\n"); // 20160624fprintf(F,"%d\n",(int)Type);int i;fprintf(F,"%d\n",iParamNum);for(i=0;i<iParamNum;i++){

fprintf(F,"%d\n",iParam[i]);}

fprintf(F,"%d\n",fParamNum);for(i=0;i<fParamNum;i++){

fprintf(F,"%f\n",fParam[i]);}

fprintf(F,"%d\n",sParam.Length());fwrite(sParam.c_str(),1,sParam.Length(),F);}

File System Save to File ASCII 형식으로 저장된 파일의 예

10

Version=1Step=9Version=11020.0000000.000000

Version=1102300.0000000.000000

Version=121120.000000300.000000Version=1

52010

Version=152120

Version=152200

Version=18120

001021210110Pattern-1Version=114100

Version=112110

File System Load From File ptGarment::LoadFromFile 함수의 작성

Step을 불러와서 regenerate 하면 됨

11

void ptGarment::LoadFromFile(AnsiString N){FILE *F=fopen(N.c_str(),"r");int Version;fscanf(F,"Version=%d\n",&Version);int i;fscanf(F,"Step=%d\n",&StepNum);Step=(ptDesignStep**)calloc(StepNum,sizeof(ptDesignStep*));for(i=0;i<StepNum;i++){

Step[i]=new ptDesignStep;Step[i]->LoadFromFile(F);}

fclose(F);Regenerate();}

File System Load From File ptDesignStep::LoadFromFile 함수의 작성

12

void ptDesignStep::LoadFromFile(FILE *F){int Version;fscanf(F,"Version=%d\n",&Version);int i,d,n;fscanf(F,"%d\n",&d);Type=(StepType)d;fscanf(F,"%d\n",&n);for(i=0;i<n;i++){

fscanf(F,"%d\n",&d);AddIntParam(d);}

fscanf(F,"%d\n",&n);float f;for(i=0;i<n;i++){

fscanf(F,"%f\n",&f);AddFloatParam(f);}

fscanf(F,"%d\n",&n);char Buf[300];fread(Buf,1,n,F);sParam=AnsiString(Buf);}

File System Binary Type ptGarment::SaveToFileBinary 함수 작성

13

void ptGarment::SaveToFileBinary(AnsiString N){TFileStream *F=new TFileStream(N,fmCreate);WriteInt(F,1); // Version,20160624WriteInt(F,StepNum);int i;for(i=0;i<StepNum;i++){

Step[i]->SaveToFileBinary(F);}

delete F;}

void ptGarment::WriteInt(TFileStream *F,int n){F->WriteBuffer(&n,sizeof(int));}

File System Binary Type ptDesignStep::SaveToFileBinary 함수 작성

14

void ptDesignStep::SaveToFileBinary(TFileStream *F){WriteInt(F,1); // Version, 20160624WriteInt(F,(int)Type);WriteInt(F,iParamNum);int i;for(i=0;i<iParamNum;i++){

WriteInt(F,iParam[i]);}

WriteInt(F,fParamNum);for(i=0;i<fParamNum;i++){

WriteFloat(F,fParam[i]);}

WriteString(F,sParam);}

void ptDesignStep::WriteInt(TFileStream *F,int n){F->WriteBuffer(&n,sizeof(int));}

void ptDesignStep::WriteFloat(TFileStream *F,float n){F->WriteBuffer(&n,sizeof(float));}

void ptDesignStep::WriteString(TFileStream *F,AnsiString S){WriteInt(F,S.Length());F->WriteBuffer(S.c_str(),S.Length());}

File System Binary Type Binary 형식으로 저장된 파일의 예

일반 text editor로 확인 불가

15

File System Binary Type ptGarment::LoadFromFileBinary 함수 작성

16

void ptGarment::LoadFromFileBinary(AnsiString N){TFileStream *F=new TFileStream(N,fmOpenRead);int Version=ReadInt(F);StepNum=ReadInt(F);Step=(ptDesignStep**)calloc(StepNum,sizeof(ptDesignStep*));int i;for(i=0;i<StepNum;i++){

Step[i]=new ptDesignStep;Step[i]->LoadFromFileBinary(F);}

delete F;Regenerate();}

int ptGarment::ReadInt(TFileStream *F){int n;F->ReadBuffer(&n,sizeof(int));return n;}

File System Binary Type ptDesignStep::LoadFromFileBinary 함수 작성

17

void ptDesignStep::LoadFromFileBinary(TFileStream *F){int Version=ReadInt(F);Type=(StepType)ReadInt(F);int n=ReadInt(F);int i;for(i=0;i<n;i++){

AddIntParam(ReadInt(F));}

n=ReadInt(F);for(i=0;i<n;i++){

AddFloatParam(ReadFloat(F));}

sParam=ReadString(F);}

int ptDesignStep::ReadInt(TFileStream *F){int n;F->ReadBuffer(&n,sizeof(int));return n;}

float ptDesignStep::ReadFloat(TFileStream *F){float f;F->ReadBuffer(&f,sizeof(float));return f;}

AnsiString ptDesignStep::ReadString(TFileStream *F){int l=ReadInt(F);char *buf=new char[l+1]F->ReadBuffer(Buf,l);buf[l]=0; // line endAnsiString N=AnsiString(buf);delete[]buf;return N;}

More on Class Access Specifier Class Member 에 대한 접근을 제한하는 키워드

Public

– 외부 process 에서 자유롭게 접근이 가능

– 코드 작성은 쉽지만 외부에서 접근이 쉬워 오류 가능성이 높아짐

Private

– 내부 변수는 내부 함수에서만 접근이 가능하게 제한

– 변수/함수가 외부와 격리 (isolation)되어 안정성이 높아지며 수정이 용이해짐

Protected

– 외부에서는 접근이 불가능하지만 상속된 클래스에서는 참조 가능

18

More on Class Access Specifier ptDesignStep 의 예

iParamNum, iParam 은 public 멤버이므로 외부에서 access 가 가능

– a=S->iParamNum; 라고 해도 되는데 굳이 a=S->GetIntParam(); 이라고 했던 이유는 ?

– s=S->iParam[5]; 라고 해도 되는데 굳이 s=S->GetIntParam(5); 라고 했던 이유는 ?

내부의 복잡한 변수 이름을 감추는 기능 (encapsulation)

만약 iParam 에 일률적으로 2를 곱한 값을 전해줘야 한다면 ?

– 전체 소스를 찾아다니면서 iParam 을 다 수정할 필요 없이 GetIntParam() 함수만 수정하면 된다

19

public:int iParamNum;int *iParam;

void AddIntParam(int);int GetIntParamNum() {return iParamNum;}int GetIntParam(int);void SetIntParam(int,int);

More on Class Access Specifier ptDesignStep 의 예

Private 키워드를 사용한 경우

– S->iParamNum; 이나 S->iParam[5]; 등의 참조 (refer, access) 가 불가능하다

– 클래스 내부 변수가 임의로 설정되지 않도록 보호해야 하는 경우 필수적

» 클래스 작동에 필수적인 변수 값을 외부에서 임으로 변경할 수 없도록 한다

20

public:

void AddIntParam(int);int GetIntParamNum() {return iParamNum;}int GetIntParam(int);void SetIntParam(int,int);

private:int iParamNum;int *iParam;

More on Class Operator Overloading 필요성

int, float 과같은 기본형 변수의 경우 사칙 연산 등을 직관적으로 할 수 있다

수학적인 요소를 class화한 경우에도 이런 연산을 할 수 없을까 ?

ptPoint Class 의 경우

ptPoint class a,b,c 를 정의했을 때

– c.Add(a,b), c.Subtract(a,b) 라는 함수를 만드는 것 보다 c=a+b, c=a-b 와 같이 쓸 수 있다면 ?

ptPoint class a,b 와 float d 를 정의했을 때

– d=a.InnerProduct(b) 라는 함수를 만드는 것보다 d=a*b 라고 쓸 수 있다면 ?

21

More on Class Operator Overloading +, - 연산과 내적 계산

응용분야

행렬, 복소수 등 여러 data class 에 적용 가능

22

class ptPoint{public:

ptPoint();~ptPoint();ptPoint(ptPoint&);

ptPoint operator+(const ptPoint& N);ptPoint operator-(const ptPoint& N);float operator*(const ptPoint& N);

};

ptPoint ptPoint::operator+(const ptPoint& N){return ptPoint (x+N.x,y+N.y);}

ptPoint ptPoint::operator-(const ptPoint& N){return ptPoint (x-N.x,y-N.y);}

float ptPoint::operator*(const ptPoint& N){return x*N.x+y*N.y;}

More on Class Inheritance SaveToFileBinary/LoadFromFileBinary 에서의 문제점

WriteInt, ReadInt, WriteFloat, ReadFloat, WriteString, ReadString 등의 함수

– 해당 클래스에서 매번 정의를 따로 해야하는 문제가 있음

– 이 함수들이 TFileStream의 멤버 함수였다면 어땠을까 ?

상속 (Inheritance)로 해결 가능

기존에 존재하는 Class 의 모든 기능을 이어받은 새로운 클래스의 작성

– TFileStream 의 모든 멤버 변수, 함수를 '상속' 받은 새로운 클래스를 만든다

– 새로운 TNewFileStream 클래스에는 int, float, AnsiString I/O 에 필요한 함수를 만들 수 있다

23

More on Class Inheritance TNewFileStream 유닛 추가

24

//---------------------------------------------------------------------------#ifndef TNewFileStreamH#define TNewFileStreamH//---------------------------------------------------------------------------

#include <vcl.h>

class TNewFileStream : public TFileStream{public :

TNewFileStream(const AnsiString, Word);

void WriteInt(int);void WriteFloat(float);void WriteString(AnsiString);int ReadInt();float ReadFloat();AnsiString ReadString();

};

#endif

More on Class Inheritance TNewFileStream 유닛 추가

25

TNewFileStream::TNewFileStream(const AnsiString N, Word T) : TFileStream(N,T){}

void TNewFileStream::WriteInt(int n){WriteBuffer(&n,sizeof(int));}

void TNewFileStream::WriteFloat(float n){WriteBuffer(&n,sizeof(float));}

void TNewFileStream::WriteString(AnsiString S){WriteInt(S.Length());WriteBuffer(S.c_str(),S.Length());}

int TNewFileStream::ReadInt(){int n;ReadBuffer(&n,sizeof(int));return n;}

float TNewFileStream::ReadFloat(){float f;ReadBuffer(&f,sizeof(float));return f;}

AnsiString TNewFileStream::ReadString(){int l=ReadInt();char *buf=new char[l+1];ReadBuffer(buf,l);buf[l]=0; // line endAnsiString N=AnsiString(buf);delete[]buf;return N;}

More on Class Inheritance ptGarment::SaveToFileBinary/LoadFromFileBinary 함수 수정

26

void ptGarment::SaveToFileBinary(AnsiString N){TNewFileStream *F=new TNewFileStream(N,fmCreate);F->WriteInt(1); // Version,20160624F->WriteInt(StepNum);int i;for(i=0;i<StepNum;i++){

Step[i]->SaveToFileBinary(F);}

delete F;}

void ptGarment::LoadFromFileBinary(AnsiString N){TNewFileStream *F=new TNewFileStream(N,fmOpenRead);int Version=F->ReadInt();StepNum=F->ReadInt();Step=(ptDesignStep**)calloc(StepNum,sizeof(ptDesignStep*));int i;for(i=0;i<StepNum;i++){

Step[i]=new ptDesignStep;Step[i]->LoadFromFileBinary(F);}

delete F;Regenerate();}

More on Class Inheritance ptDesignStep::SaveToFileBinary/LoadFromFileBinary 함수 수정

27

void ptDesignStep::SaveToFileBinary(TNewFileStream *F){F->WriteInt(1); // Version, 20160624F->WriteInt((int)Type);F->WriteInt(iParamNum);int i;for(i=0;i<iParamNum;i++){

F->WriteInt(iParam[i]);}

F->WriteInt(fParamNum);for(i=0;i<fParamNum;i++){

F->WriteFloat(fParam[i]);}

F->WriteString(sParam);}

void ptDesignStep::LoadFromFileBinary(TNewFileStream *F){int Version=F->ReadInt();Type=(StepType)F->ReadInt();int n=F->ReadInt();int i;for(i=0;i<n;i++){

AddIntParam(F->ReadInt());}

n=F->ReadInt();for(i=0;i<n;i++){

AddFloatParam(F->ReadFloat());}

sParam=F->ReadString();}