반응형

학생 클래스 구현

작성자 : 장 문석

작성일 : 2011-04-28

캡슐화 개요 샘플

 

*본 샘플은 캡슐화 개요 실습에 대한 샘플임*

 3.   멤버 형식 정의

Stu클래스에 구현해야 할 사항을 파악하여 필요한 멤버 목록을 작성하였으면 각 멤버의 형식을 정의해야 할 것이다. 멤버 필드는 외부 scope에서 접근하지 못하게 가시성을 차단하고 이에 대한 참조나 변경이 필요한 경우에는 멤버 메서드를 통해 접근할 수 있도록 하자.

 

num(학생 번호)의 경우 변경하지 못하게 const 멤버로 해야 할 것이다.

const int num;

생성자는 번호와 이름을 입력 인자로 전달받기로 했기 때문에 이를 반영해야 할 것이다.

Stu(int _num,const char *_name);

 

GetNum, GetName, View 메서드는 멤버 필드를 변경하지 않음을 명시하자. 이를 통해 개발 중 실수를 미연에 방지할 수 있고 우리가 작성한 클래스를 사용하는 이와 불필요한 의사 소통을 줄일 수 있을 것이다.

           int GetNum()const;

           const char *GetName()const;

           void View()const;

 

Stu.h

#pragma once

#include "StuProperty.h"

#define MAX_NAME_LEN        20

class Stu

{         

           char name[MAX_NAME_LEN+1];

           const int num;

           int hp;

           int iq;

           int stress;

           int scnt;         

public:

           Stu(int _num,const char *_name);       

           virtual ~Stu();

           void Dance();

           void Drink();

           void Study();

           void ListenLecture();

           void Relax();

           void Sleep();

           int GetNum()const;

           const char *GetName()const;

           void View()const;

};

 

소스 코드에 멤버 메서드를 추가하자.

num 멤버 필드는 상수화 멤버이므로 initialize를 해 주어야 한다.

Stu::Stu(int _num,const char *_name):num(_num)

{         

}

 

Stu.cpp

#include "Stu.h"

 

Stu::Stu(int _num,const char *_name):num(_num)

{         

}

Stu::~Stu()

{

}

 

void Stu::Dance()

{         

}

void Stu::Drink()

{         

}

void Stu::Study()

{

}

void Stu::ListenLecture()

{

}

void Stu::Relax()

{         

}

void Stu::Sleep()

{         

}

int Stu::GetNum()const

{

           return num;

}

const char *Stu::GetName()const

{

           return name;

}

void Stu::View()const

{

}

 

본 샘플에서는 시나리오에서 정한 상수들을 별도의 클래스에 정적 상수화 멤버로 정의하였다.

StuProperty.h

#pragma once

#include "Default.h"

class StuProperty

{

public:

           static const int def_hp;

           static const int min_hp;

           static const int max_hp;

           static const int def_iq;

           static const int min_iq;

           static const int max_iq;

           static const int def_stress;

           static const int min_stress;

           static const int max_stress;

           static const int def_scnt;

           static const int min_scnt;

           static const int max_scnt;       

};

 

 

정적 멤버 필드는 클래스 정의 구문 외부에 선언해 주어야 한다.

StuProperty.cpp

#include "StuProperty.h"

 

const int StuProperty::def_hp = 50;

const int StuProperty::min_hp = 0;

const int StuProperty::max_hp = 100;

const int StuProperty::def_iq = 100;

const int StuProperty::min_iq = 80;

const int StuProperty::max_iq = 200;

const int StuProperty::def_stress = 0;

const int StuProperty::min_stress = 0;

const int StuProperty::max_stress = 100;

const int StuProperty::def_scnt = 0;

const int StuProperty::min_scnt = 0;

const int StuProperty::max_scnt = 5;

 

 

프로그램에서 사용할 기본 요소들을 포함시키기 위한 별도의 헤더 파일을 추가하였다.

Default.h 프로젝트에서 사용할 기본 요소 정의

#pragma once

 

#pragma warning(disable:4996)

#include <string.h>

#include <iostream>

using std::cout;

using std::endl;

using std::cin;

 

단위 테스트를 하기 위한 코드이다. 통합 테스트 전에 단위 테스트를 수행함으로써 기하 급수적으로 늘어날 수 있는 버그를 줄일 수 있다.

Example.cpp 작성한 Stu를 테스트 하기 위한 코드

#include "Stu.h"

 

void main()

{

           Stu *s = new Stu(1,"홍길동");  

           s->View();

 

           s->Study();     

           s->Study();

           s->ListenLecture();

           s->View();

 

           s->Study();

           s->Drink();

           s->Dance();

           s->Sleep();

           s->View();

 

           s->Study();

           s->Relax();

           s->View();

 

           delete s;

           cin.get();         

}

  

 4.   멤버 메서드 구현

본 샘플에서 구현할 시나리오를 보면 여러 행위에서 공통적으로 iq나 hp와 같은 멤버 필드의 값을 변경을 해야 하는데 이들의 변경 가능한 최대치와 최소치가 존재하고 있다. 결국, 각 행위에서는 변경해야 할 멤버 필드가 한계가 벗어나지 않는 범위에서 변경을 해야 하는데 이에 대한 처리를 하는 서브 메서드를 만들고 이들을 호출하는 방식으로 작성하였다.

void Stu::Dance()

{         

          

           SetIq(iq-3);

          

}

 

void Stu::Drink()

{         

          

           SetIq(iq-4);

      

}

 

 

void Stu::SetIq(int _iq)

{

           if(_iq>=StuProperty::max_iq)

           {

                     _iq = StuProperty::max_iq;

           }

           else

           {

                     if(_iq<StuProperty::min_iq)

                     {

                                _iq = StuProperty::min_iq;

                     }

           }

 

           iq =_iq;

}

 

여기에서의 SetIq와 같은 멤버 메서드는 클래스 내부 scope에서 사용을 목적으로 만든 것이기 때문에 외부에서 접근하지 못하게 가시성을 private으로 두어 신뢰성을 높일 수 있다.

 

Stu.cpp

#include "Stu.h"

 

Stu::Stu(int _num,const char *_name):num(_num)

{

           memset(name,0,sizeof(name));

           strncpy(name,_name,MAX_NAME_LEN);         

           InitProproperty();

#if _DEBUG

           cout<<name<<" 생성"<<endl;

#endif

}

Stu::~Stu()

{

#if _DEBUG

           cout<<name<<" 소멸"<<endl;

#endif

}

 

void Stu::Dance()

{         

           cout<<name<<" 춤추다."<<endl;

           SetIq(iq-3);

           SetHp(hp-30);

           SetStress(stress-20);

           SetScnt(0);

}

void Stu::Drink()

{         

           cout<<name<<" 마시다."<<endl;

           SetIq(iq-4);

           SetHp(hp-20);

           SetStress(stress-10);

           SetScnt(0);

}

void Stu::Study()

{

           cout<<name<<" 공부하다."<<endl;

           SetIq(iq+(5-scnt));

           SetHp(hp-5);

           SetStress(stress+10);

           SetScnt(scnt+1);

}

void Stu::ListenLecture()

{

           cout<<name<<" 강의를듣다."<<endl;

           SetIq(iq+scnt);

           SetHp(hp-10);

           SetStress(stress+(20 - scnt*5));

           SetScnt(0);

}

void Stu::Relax()

{         

           cout<<name<<" 휴식을취한다."<<endl;

           SetHp(hp+30);

           SetStress(stress-20);

           SetScnt(0);

}

void Stu::Sleep()

{

           cout<<name<<" 잠을잔다."<<endl;

           SetHp(hp+50);

           SetStress(stress-50);

           SetScnt(0);      

}

int Stu::GetNum()const

{

           return num;

}

const char *Stu::GetName()const

{

           return name;

}

void Stu::View()const

{

           cout<<name<<endl;

           cout<<번호:"<<num<<endl;

           cout<<아이큐:"<<iq<<endl;

           cout<<체력:"<<hp<<endl;

           cout<<스트레스:"<<stress<<endl; 

}

 

////////////private 멤버 메서드//////////////////

void Stu::InitProproperty()

{

           hp =StuProperty::def_hp;

           iq =StuProperty::def_iq;

           stress =StuProperty::def_stress;

           scnt =StuProperty::def_scnt;

}

 

void Stu::SetIq(int _iq)

{

           if(_iq>=StuProperty::max_iq)

           {

                     _iq = StuProperty::max_iq;

           }

           else

           {

                     if(_iq<StuProperty::min_iq)

                     {

                                _iq = StuProperty::min_iq;

                     }

           }

 

           iq =_iq;

}

void Stu::SetHp(int _hp)

{         

           if(_hp>=StuProperty::max_hp)

           {

                     _hp = StuProperty::max_hp;

           }

           else

           {

                     if(_hp<StuProperty::min_hp)

                     {

                                _hp = StuProperty::min_hp;

                     }

           }

 

           hp =_hp;

}

void Stu::SetStress(int _stress)

{         

           if(_stress>=StuProperty::max_stress)

           {

                     _stress = StuProperty::max_stress;

           }

           else

           {

                     if(_stress<StuProperty::min_stress)

                     {

                                _stress = StuProperty::min_stress;

                     }

           }         

           stress =_stress;

}

void Stu::SetScnt(int _scnt)

{         

           if(_scnt>=StuProperty::max_scnt)

           {

                     _scnt = StuProperty::max_scnt;

           }

           else

           {

                     if(_scnt<StuProperty::min_scnt)

                     {

                                _scnt = StuProperty::min_scnt;

                     }

           }

           scnt =_scnt;

}

 

멤버 메서드 구현 과정에서 SetIq와 같은 클래스 내부 scope에서 사용할 메서드를 클래스 정의문에 추가하였다.

private:

           void InitProproperty();

           void SetIq(int _iq);

           void SetHp(int _hp);

           void SetStress(int _stress);

           void SetScnt(int _scnt);

 

Stu.h

#pragma once

#include "StuProperty.h"

 

#define MAX_NAME_LEN        20

class Stu

{         

           char name[MAX_NAME_LEN+1];

           const int num;

           int hp;

           int iq;

           int stress;

           int scnt;         

public:

           Stu(int _num,const char *_name);       

           virtual ~Stu();

           void Dance();

           void Drink();

           void Study();

           void ListenLecture();

           void Relax();

           void Sleep();

           int GetNum()const;

           const char *GetName()const;

           void View()const;

private:

           void InitProproperty();

           void SetIq(int _iq);

           void SetHp(int _hp);

           void SetStress(int _stress);

           void SetScnt(int _scnt);

};


출처 : 짱강

http://cafe.daum.net/smbitpro?t__nil_cafemy=item

반응형

'프로그래밍 > Language C++' 카테고리의 다른 글

[C++]오버로딩 과 오버라이딩  (0) 2013.03.31
[C++] 연산자 오버로딩 연습  (0) 2012.05.30
[C++] 캡슐화 개요  (0) 2011.11.16
[C++] C++ is a c with class  (0) 2011.11.16