class Employee {
std::string name;
int age;
std::string position; // 직책 (이름)
int rank; // 순위 (값이 클 수록 높은 순위)
public:
Employee(std::string name, int age, std::string position, int rank)
: name(name), age(age), position(position), rank(rank) {}
// 복사 생성자
Employee(const Employee& employee) {
name = employee.name;
age = employee.age;
position = employee.position;
rank = employee.rank;
}
// 디폴트 생성자
Employee() {}
void print_info() {
std::cout << name << " (" << position << " , " << age << ") ==> "
<< calculate_pay() << "만원" << std::endl;
}
int calculate_pay() { return 200 + rank * 50; }
};
class EmployeeList {
int alloc_employee; // 할당한 총 직원 수
int current_employee; // 현재 직원 수
Employee** employee_list; // 직원 데이터
public:
EmployeeList(int alloc_employee) : alloc_employee(alloc_employee) {
employee_list = new Employee*[alloc_employee];
current_employee = 0;
}
void add_employee(Employee* employee) {
// 사실 current_employee 보다 alloc_employee 가 더
// 많아지는 경우 반드시 재할당을 해야 하지만, 여기서는
// 최대한 단순하게 생각해서 alloc_employee 는
// 언제나 current_employee 보다 크다고 생각한다.
// (즉 할당된 크기는 현재 총 직원수 보다 많음)
employee_list[current_employee] = employee;
current_employee++;
}
int current_employee_num() { return current_employee; }
void print_employee_info() {
int total_pay = 0;
for (int i = 0; i < current_employee; i++) {
employee_list[i]->print_info();
total_pay += employee_list[i]->calculate_pay();
}
std::cout << "총 비용 : " << total_pay << "만원 " << std::endl;
}
~EmployeeList() {
for (int i = 0; i < current_employee; i++) {
delete employee_list[i];
}
delete[] employee_list;
}
};
이때 차장 이상 급들은 관리데이터에 근속 년수를 포함시켜서 월급에 추가해달라는 요청이 들어옴.
-> 이럴 경우 Manager 클래스를 추가하면서 Employee 클래스와 비슷하게 만들되, calculate_pay 함수부분을 다르게 해야 한다.
=> 그런데 calculate_pay 부분만 다르게 하자고 Employee 클래스를 거의 복붙해서 코드 양을 비효율적으로 늘릴 수는 없다.
Manager 클래스를 상속을 사용해서 덜 비효율적으로 코드를 작성해 보자.
#include <iostream>
#include <string>
class Base {
std::string s;
public:
Base() : s("기반") { std::cout << "기반 클래스" << std::endl; }
void what() { std::cout << s << std::endl; }
};
class Derived : public Base {
std::string s;
public:
Derived() : Base(), s("파생") {
std::cout << "파생 클래스" << std::endl;
// Base 에서 what() 을 물려 받았으므로
// Derived 에서 당연히 호출 가능하다
what();
}
};
int main() {
std::cout << " === 기반 클래스 생성 ===" << std::endl;
Base p;
std::cout << " === 파생 클래스 생성 ===" << std::endl;
Derived c;
return 0;
}
class Derived : public Base
는 Derived가 Base를 public 형식으로 상속을 받겠다는 의미가 된다.
❗ 또 하나 눈여겨 봐야 할 점은 Derived의 생성자 호출 부분이다.
Derived(): Base(), s("파생")
부분에서 초기화 리스트에서 Base를 통해 기반의 생성자를 먼저 호출한다.
이때 기반 클래스의 생성자를 명시적으로 호출하지 않을 경우 기반 클래스의 디폴트 생성자가 호출됨.
what() 함수 호출 부분을 보자.
what() 함수는 Base에 정의가 되어있어 Derived의 s가 아니라 Base의 s가 출력되어 "기반"이라고 나오게 된다.
이번에는 what 함수를 Derived에도 추가해보자.
사실 두 함수는 같은 이름이지만, 다른 클래스에 정의되어 있는 것이기 때문에 다른 함수로 취급된 거임.
#include <iostream>
#include <string>
class Base {
std::string s;
public:
Base() : s("기반") { std::cout << "기반 클래스" << std::endl; }
void what() { std::cout << s << std::endl; }
};
class Derived : public Base {
std::string s;
public:
Derived() : Base(), s("파생") {
std::cout << "파생 클래스" << std::endl;
what();
}
void what() { std::cout << s << std::endl; }
};
int main() {
std::cout << " === 기반 클래스 생성 ===" << std::endl;
Base p;
std::cout << " === 파생 클래스 생성 ===" << std::endl;
Derived c;
return 0;
}
Derived의 what 함수가 Base의 what 함수를 오버라이딩한 걸 볼 수 있음.
참고: https://velog.io/@choi_612/CPP4
class A : public(접근 지시자) B
기반 클래스의 접근 지시자들에 영향 없이 그대로 작동
public 은 protected로 바뀜 나머지는 그대로 유지
모든 접근 지시자들이 private으로 바뀜