[C++] 캡슐화 개요 샘플
|
작성자 : 장 문석 |
작성일 : 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); }; |
출처 : 짱강
'프로그래밍 > 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 |
댓글
이 글 공유하기
다른 글
-
[C++]오버로딩 과 오버라이딩
[C++]오버로딩 과 오버라이딩
2013.03.31 -
[C++] 연산자 오버로딩 연습
[C++] 연산자 오버로딩 연습
2012.05.30 -
[C++] 캡슐화 개요
[C++] 캡슐화 개요
2011.11.16 -
[C++] C++ is a c with class
[C++] C++ is a c with class
2011.11.16