[디딤돌 C++] 42. 상속과 다형성 최종 실습 – 학생

이제 상속과 다형성의 마지막 실습 시나리오를 보고 설계 및 구현해 보기로 해요.

시나리오를 보면 정의할 형식은 학생, 학사 학생, 운동학생, 마법학생이 있습니다. 학생을 기반 클래스로 정의하고 나머지 클래스는 파생 클래스로 정의하면 되겠죠.

학생 클래스 일반화 클래스 다이어그램

먼저 학생 클래스에 필요한 멤버들을 고민해 보기로 해요.

학생 클래스는 멤버 필드로 이름, 주민번호, 체력, 지력, 스트레스와 연속으로 공부한 횟수가 필요합니다.

그리고 주민번호를 순차적으로 부여하기 위해서는 정적 멤버로 가장 최근에 부여한 주민번호가 필요하겠죠.

그리고 멤버 메서드로 “공부하다.”, “자습하다.”, “잠자다.”, “휴식하다.”, “음료마시다.”, “노래하다.”가 필요합니다. 그리고 이들 메서드는 파생 형식에 따라 멤버 필드를 변경하는 값이 달라서 순수 가상 메서드로 정의합시다.

이 외에 생성자가 필요하고 각 멤버의 값에 접근하는 접근자 메서드를 제공합시다.

이 외에 개체의 정보를 출력하는 가상 메서드를 제공합시다.

특히 파생 형식에서 개체의 멤버 필드 값을 변경할 수 있어야 합니다.

이를 위해 각 멤버의 값을 설정하는 설정자를 protected 접근 지정으로 제공합시다.

여기에서는 체력, 지력, 스트레스, 연속으로 공부한 횟수의 디폴트, 최대, 최소 값을 정적 클래스로 정의하여 사용하게 할게요.

클래스 다이어그램

여기까지 프로젝트에 표현한 후에 다음 작업을 진행하세요.

//StuConst.h
#pragma once
class StuConst
{
public:
    static const int def_iq;
    static const int max_iq;
    static const int min_iq;
    static const int def_hp;
    static const int max_hp;
    static const int min_hp;
    static const int def_stress;
    static const int max_stress;
    static const int min_stress;
    static const int def_scnt;
    static const int max_scnt;
    static const int min_scnt;  
private://개체를 생성할 수 없게 함
    StuConst(void);    
};
//StuConst.cpp
#include "StuConst.h"
const int StuConst::def_iq = 100;
const int StuConst::max_iq=200;
const int StuConst::min_iq=0;    
         
const int StuConst::def_hp=100;
const int StuConst::max_hp=200;
const int StuConst::min_hp=0;     
        
const int StuConst::def_stress=0;
const int StuConst::max_stress=100;
const int StuConst::min_stress=0;   
         
const int StuConst::def_scnt=0;
const int StuConst::max_scnt=5;
const int StuConst::min_scnt=0;
StuConst::StuConst(void)
{
}
//Student.h
#pragma once
#include "StuConst.h"
#include <iostream>
#include <string>
using namespace std;

class Student
{
    static int last_pn;
    const int pn;
    string name;
    int iq;
    int hp;
    int stress;
    int scnt;
public:
    Student(string name);
    virtual void Study()=0;
    virtual void ListenLecture()=0;
    virtual void Sleep()=0;
    virtual void Relax()=0;
    virtual void Drink()=0;
    virtual void Sing()=0;
    virtual void View()const;
    int GetPN()const;
    string GetName()const;
    int GetIQ()const;
    int GetHP()const;
    int GetStress()const;
    int GetSCnt()const;
protected:
    void SetIQ(int iq);
    void SetHP(int hp);
    void SetStress(int stress);
    void SetSCnt(int scnt);    
};
//Student.cpp
#include "Student.h"
#define SC StuConst //간략하게 사용할 수 있게 매크로 정의
int Student::last_pn;

Student::Student(string name):pn(++last_pn)
{
    this->name = name;
    SetIQ(SC::def_iq);
    SetHP(SC::def_hp);    
    SetStress(SC::def_stress);
    SetSCnt(SC::def_scnt);
}
void Student::View()const
{
    cout<<"주민 번호:"<<pn<<" 이름:"<<name<<endl;
    cout<<"  IQ:"<<iq<<" HP:"<<hp<<" Stress:"<<stress<<endl;
    cout<<"  연속으로 공부한 횟수:"<<scnt<<endl;
}
int Student::GetPN()const
{
    return pn;
}
string Student::GetName()const
{
    return name;
}
int Student::GetIQ()const
{
    return iq;
}
int Student::GetHP()const
{
    return hp;
}
int Student::GetStress()const
{
    return stress;
}
int Student::GetSCnt()const
{
    return scnt;
}

void Student::SetIQ(int iq)
{
    if(iq>SC::max_iq)
    {
        iq = SC::max_iq;
    }
    if(iq<SC::min_iq)
    {
        iq = SC::min_iq;
    }
    this->iq = iq;
}

void Student::SetHP(int hp)
{
    if(hp>SC::max_hp)
    {
        hp = SC::max_hp;
    }
    if(hp<SC::min_hp)
    {
        hp = SC::min_hp;
    }
    this->hp = hp;
}

void Student::SetStress(int stress)
{
    if(stress>SC::max_stress)
    {
        stress = SC::max_stress;
    }

    if(stress<SC::min_stress)
    {
        stress = SC::min_stress;
    }
    this->stress = stress;
}
void Student::SetSCnt(int scnt)
{
    if(scnt>SC::max_scnt)
    {
        scnt = SC::max_scnt;
    }
    if(scnt<SC::min_scnt)
    {
        scnt = SC::min_scnt;
    }
    this->scnt = scnt;
}
//SStudent.h
#pragma once
#include "student.h"
class SStudent :
    public Student
{
public:
    SStudent(string name);    
};
//SStudent..cpp
#include "SStudent.h"
SStudent::SStudent(string name):Student(name)
{
}
//MStudent.h
#pragma once
#include "student.h"
class MStudent :
    public Student
{
public:
    MStudent(string name);
};
//MStudent.cpp
#include "MStudent.h"
MStudent::MStudent(string name):Student(name)
{
}
//PStudent.h
#pragma once
#include "student.h"
class PStudent :
    public Student
{
public:
    PStudent(string name);
};
//PStudent..cpp
#include "PStudent.h"
PStudent::PStudent(string name):Student(name)
{
}
//Program.cpp
#include "SStudent.h"
#include "MStudent.h"
#include "PStudent.h"
int main()
{
    return 0;
}