1. Employee.h
Employee 클래스는 Employee.h 파일에 정의한다.
이 파일에 들어있는 코드를 하나씩 살펴보자.
#pragma once
#include <string>
namespace Records {
첫 번째 줄에 있는 #pragma once는 같은 파일을 여러 번 불러오지(임포트하지)않게 해 준다.
이어서 string 기능을 불러오는 문장이 나온다.
그다음은 중괄호 안에 담긴 코드가 Records란 네임스페이스에 속하도록 선언한다.
const int kDefaultStartingSalary = 30000;
그 뒤에 나오는 상수는 신입직원의 기본 급여를 정의한다.
이 상수는 Records 네임스페이스에 속하기 때문에 Records에 속한 코드에서는 kDefaultStartingSalary라고만 적어도 접근할 수 있다. 다른 네임스페이스에서 접근할 때는 반드시 :: (스코프 지정 연산자)를 사용하여 참조해야 한다.
class Employee
{
public:
Employee() = default;
Employee(const std::string& firstName,
const std::string& lastName);
void promote(int raiseAmount = 1000);
void demote(int demeritAmount = 1000);
void hire(); // 직원을 채용하거나 재임용한다.
void fire(); // 직원을 해고한다.
void display() const; // 지구언 정보를 콘솔에 출력한다.
// 게터와 세터
void setFirstName(const std::string& firstName);
const std::string& getFirstName() const;
void setLastName(const std::string& lastName);
const std::string& getLastName() const;
void setEmployeeNumber(int employeeNumber);
int getEmployeeNumber() const;
void setSalary(int newSalary);
int getSalary() const;
bool isHired() const;
다음으로 Employee 클래스를 정의한다.
먼저 public 메서드인 promote()와 demote()를 정의한다.
둘 다 정수 타입 매개변수를 받는데, 내부에 기본값이 지정돼 있어서 이 메서드를 호출할 때 정수 매개변수를 빠뜨리면 자동으로 기본값을 사용한다. 직원에 대한 정보를 변경하거나 조회할 수 있도록 여러 가지 세터와 게터를 정의한다.
private:
std::string mFirstName;
std::string mLastName;
int mEmployeeNumber = -1;
int mSalary = kDefaultStartingSalary;
bool mHired = false;
};
}
마지막으로 데이터 멤버를 정의했다.
다른 코드에서 데이터 멤버를 직접 수정할 수 없도록 private로 선언했다.
게터와 세터를 통해서만 외부에서 이 값을 조회하거나 수정할 수 있다.
또한 데이터 멤버에 대한 초깃값을 생성자로 지정하지 않고 여기서 곧바로 초기화했다.
2. Employee.cpp
여기서 생성자는 성과 이름에 대한 인수를 받아 각각의 값을 해당 데이터 멤버에 설정하기만 한다.
#include <iostream>
#include "Employee.h"
using namespace std;
namespace Records{
Employee::Employee(const std::string& firstName,
const std::string& lastName)
: mFirstName(firstName), mLastName(lastName)
{
}
promote()와 demote() 메서드는 단순히 인수로 전달된 값을 각자의 의미에 맞게 바꿔서 setSalary() 메서드에 넘겨준다.
void Employee::promote(int raiseAmount)
{
setSalary(getSalary() + raiseAmount);
}
void Employee::demote(int demeritAmount)
{
setSalary(getSalary() - demeritAmount);
}
코드를 보면 정수 타입 매개변수에 대한 기본 값이 소스 파일에 나와 있지 않다.
이러한 기본 값은 함수를 구현하는 코드가 아닌 선언하는 코드에서만 지정할 수 있기 때문이다.
hire()와 fire() 메서드는 mHired 데이터 멤버를 적절히 설정한다.
void Employee::hire()
{
mHired = true;
}
void Employee::fire()
{
mHired = false;
}
display() 메서드는 현재 직원에 대한 정보를 콘솔 출력 스트림으로 화면에 표시한다.
void Employee::display() const
{
cout << "Employee: " << getLastName() << ", " << getFirstName() << endl;
cout << "-------------------------" << endl;
cout << (isHired() ? "Current Employee" : "Former Employee") << endl;
cout << "Employee Number: " << getEmployeeNumber() << endl;
cout << endl;
}
값을 가져오거나 설정하는 작업은 여러 가지 게터와 세터로 처리한다.
// 게터와 세터
void Employee::setFirstName(const string& firstName)
{
mFirstName = firstName;
}
const string& Employee::getFirstName() const
{
return mFirstName;
}
// ... 공간 절약을 위해 그 밖에 다른 게터와 세터는 생략함
}
데이터 멤버를 public으로 선언하는 것보다 이렇게 게터와 세터를 구현하는 것이 낫다.
급여를 조회하거나 설정하는 시점의 값을 확인할 수 있기 때문에 디버깅이 쉽기 때문이다.
3. EmployeeTest.cpp
작성한 클래스마다 테스트 코드도 함께 작성하면 좋다.
다음 코드는 main() 함수에서 Employee 클래스의 연산을 간단히 테스트하는 예를 보여주고 있다.
임시로 테스트하는 것이기에 테스트가 정상적으로 작동하면 이 부분을 삭제하거나 주석 처리를 하면 된다.
#include <iostream>
#include "Employee.h"
using namespace std;
using namespace Records;
int main()
{
cout << "Testing the Employee class." << endl;
Employee emp;
emp.setFirstName("John");
emp.setLastName("Doe");
emp.setEmployeeNumber(71);
emp.setSalary(50000);
emp.promote();
emp.promote(50);
emp.hire();
emp.display();
return 0;
}
결과
'💻프로그래밍 내용 정리 > C++17' 카테고리의 다른 글
[C++ 1.6.4] 사용자 인터페이스 (0) | 2022.08.19 |
---|---|
[C++ 1.6.3] Database 클래스 (0) | 2022.08.18 |
[C++ 1.6.1] C++ 프로그램 만들기(직원 관리 시스템) (0) | 2022.08.18 |
[C++ 1.5.1] 표준 라이브러리 (0) | 2022.08.18 |
[C++ 1.4.1] 직접 리스트 초기화와 복제 리스트 초기화 (0) | 2022.08.18 |