상속은 적용이 중요한 문법이다. 적절할 때 선별적으로 적용할 수 있어야 한다.
#include <iostream>
#include <cstring>
using namespace std;
class PermenentWorker	//데이터적 성격이 강한 클래스
{
    private:
        char name[100];
        int salary;
    public:
        PermenentWorker(char* name, int money)
            :salary(money)
        {
            strcpy(this->name, name);
        }
        int GetPay(void) const
        {
            return salary;
        }
        void ShowSalaryInfo(void) const
        {
            cout<<"name: "<<name<<endl;
            cout<<"salary: "<<GetPay()<<endl<<endl;
        }
};
class EmployeeHandler		//기능적 성격이 강한 클래스(컨트롤 클래스)
{
    private:
        PermenentWorker* empList[50];
        int empNum;
    public:
        EmployeeHandler() :empNum(0)
		{}
        void AddEmployee(PermenentWorker* emp)	//새로운 직원정보 등록
        {
            empList[empNum++] = emp;
        }
        void ShowAllSalaryInfo(void) const	        //모든 직원의 급여정보 출력
        {
            for(int i=0; i<empNum; i++)
                empList[i]->ShowSalaryInfo();
        }	
        void ShowTotalSalary(void) const	    //급여의 총액 출력
        {
            int sum=0;
            for(int i=0; i<empNum; i++)
                sum += empList[i]->GetPay();
            cout<<"salary sum: "<<sum<<endl;
        }
        ~EmployeeHandler()
        {
            for(int i=0; i<empNum; i++)
                delete empList[i];
        }
};
int main(void)
{
    EmployeeHandler handler;
    handler.AddEmployee(new PermenentWorker("asdf", 1000));
    handler.AddEmployee(new PermenentWorker("xcv", 2332));
    handler.ShowAllSalaryInfo();
    handler.ShowTotalSalary();
    return 0;
}

기능의 처리를 실제로 담당하는 클래스를 가리켜 '컨트롤(control) 클래스' 또는 '핸들러(handler) 클래스' 라 한다.
※ 컨트롤 클래스는 기능 제공의 핵심이 되기 때문에 모든 객체지향 프로그램에서 반드시 존재하는 클래스이다.
※ 멤버는 클래스가 정의될 때, 멤버의 초기화를 목적으로 정의된 생성자를 통해서 초기화하는 것이 가장 안정적이다. 그것이 비록 상속의 관계로 묶여있다 할지라도.
◆ 용어 정리 ◆
상위 클래스                ↔                하위 클래스
기초(base) 클래스      ↔                유도(derived) 클래스
슈퍼(super) 클래스    ↔                서브(sub) 클래스
부모 클래스               ↔                자식 클래스
#include <iostream>
using namespace std;
class Base
{
    private:
        int baseNum;
    public:
        Base(void) :baseNum(20)
        {
        cout<<"Base(void)"<<endl;
        }
        Base(int n) :baseNum(n)
        {
        cout<<"Base(int n)"<<endl;
        }
        void ShowBaseData()
        {
            cout<<baseNum<<endl;
        }
};
class Derived :public Base
{
    private:
        int derivedNum;
    public:
        Derived() :derivedNum(30)
        {
        cout<<"Derived()"<<endl;
        }
        Derived(int n) : derivedNum(n)
        {
        cout<<"Derived(int n)"<<endl;
        }
        Derived(int n1, int n2)
            : Base(n1), derivedNum(n2)
        {
            cout<<"Derived(int n1, int n2)"<<endl;
        }
        void ShowDerivedData()
        {
            ShowBaseData();
            cout<<derivedNum<<endl;
        }
};
int main(void)
{
    cout<<"case1......"<<endl;
    Derived dr1;
    dr1.ShowDerivedData();
    cout<<"case2........."<<endl;
    Derived dr2(12);
    dr2.ShowDerivedData();
    cout<<"case3..........."<<endl;
    Derived dr3(14, 15);
    dr3.ShowDerivedData();
    return 0;
}

위의 소스코드로 알 수 있는 점 두가지.
1. 유도 클래스의 객체 생성 과정에서 기초 클래스의 생성자는 100% 호출이 된다.
2. 유도 클래스의 생성자에서 기초 클래스의 생성자 호출을 명시하지 않으면, 기초 클래스의 void 생성자가 호출이 된다.
★ "클래스의 멤버는 해당 클래스의 생성자를 통해서 초기화해야 한다."
유도 클래스 객체의 소멸과정

위의 결과로 알 수 있는 사실.
1. 유도 클래스의 객체가 소멸될 때에는, 유도 클래스의 소멸자가 실행되고 난 다음에 기초 클래스의 소멸자가 실행된다.
2. 스택에 생성된 객체의 소멸순서는 생성순서와 반대이다.
※ 이러한 객체소멸의 특성 때문에 상속과 연관된 클래스의 소멸자는 "생성자에서 동적 할당한 메모리 공간은 소멸자에서 해제한다" 는 원칙을 지켜서 정의해야 한다.
#include <iostream>
#include <cstring>
using namespace std;
class Person
{
    private:
        char* name;
        
    public:
        Person(char* name)
        {
            this->name = new char[strlen(name)+1];
            strcpy(this->name, name);
        }
        ~Person()
        {
            delete []name;
        }
        void WhatYourName() const
        {
            cout<<"My name is "<<name<<endl;
        }
};
class UnivStudent : public Person
{
    private:
        char* major;
    public:
        UnivStudent(char* name, char* major)
            :Person(name)
        {
            this->major = new char[strlen(major)+1];
            strcpy(this->major, major);
        }
        ~UnivStudent()
        {
            delete []major;
        }
        void WhoAreYou() const
        {
            WhatYourName();
            cout<<"My major is "<<major<<endl<<endl;
        }
};
int main(void)
{
    UnivStudent st1("Jeon", "Houdini");
    st1.WhoAreYou();
    UnivStudent st2("Seo", "Maya");
    st2.WhoAreYou();
    return 0;
}
