8. 상속과 다형성
출처: 윤성우 열혈강의 C++ 예제코드
8.1. 객체 포인터의 참조관계
- Base Class형 변수로 Derived Class 객체 다루기
#include <iostream>
using namespace std;
class Person
{
public:
void Sleep() { cout<<"Sleep"<<endl; }
};
class Student : public Person
{
public:
void Study() { cout<<"Study"<<endl; }
};
class PartTimeStudent : public Student
{
public:
void Work() { cout<<"Work"<<endl; }
};
int main(void)
{
Person * ptr1=new Student();
Person * ptr2=new PartTimeStudent();
Student * ptr3=new PartTimeStudent();
ptr1->Sleep();
ptr2->Sleep();
ptr3->Study();
delete ptr1; delete ptr2; delete ptr3;
return 0;
}
8.2. 가상함수(Vitual Function)
- 가상함수를 이용하여 override한 함수 호출하기(포인터)
#include <iostream>
#include <cstring>
using namespace std;
class Employee
{
private:
char name[100];
public:
Employee(char * name)
{
strcpy(this->name, name);
}
void ShowYourName() const
{
cout<<"name: "<<name<<endl;
}
virtual int GetPay() const
{
return 0;
}
virtual void ShowSalaryInfo() const
{ }
};
class PermanentWorker : public Employee
{
private:
int salary;
public:
PermanentWorker(char * name, int money)
: Employee(name), salary(money)
{ }
int GetPay() const
{
return salary;
}
void ShowSalaryInfo() const
{
ShowYourName();
cout<<"salary: "<<GetPay()<<endl<<endl;
}
};
class TemporaryWorker : public Employee
{
private:
int workTime;
int payPerHour;
public:
TemporaryWorker(char * name, int pay)
: Employee(name), workTime(0), payPerHour(pay)
{ }
void AddWorkTime(int time)
{
workTime+=time;
}
int GetPay() const
{
return workTime*payPerHour;
}
void ShowSalaryInfo() const
{
ShowYourName();
cout<<"salary: "<<GetPay()<<endl<<endl;
}
};
class SalesWorker : public PermanentWorker
{
private:
int salesResult; // 월 판매실적
double bonusRatio; // 상여금 비율
public:
SalesWorker(char * name, int money, double ratio)
: PermanentWorker(name, money), salesResult(0), bonusRatio(ratio)
{ }
void AddSalesResult(int value)
{
salesResult+=value;
}
int GetPay() const
{
return PermanentWorker::GetPay()
+ (int)(salesResult*bonusRatio);
}
void ShowSalaryInfo() const
{
ShowYourName();
cout<<"salary: "<<GetPay()<<endl<<endl;
}
};
class EmployeeHandler
{
private:
Employee* empList[50];
int empNum;
public:
EmployeeHandler() : empNum(0)
{ }
void AddEmployee(Employee* emp)
{
empList[empNum++]=emp;
}
void ShowAllSalaryInfo() const
{
for(int i=0; i<empNum; i++)
empList[i]->ShowSalaryInfo();
}
void ShowTotalSalary() 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 PermanentWorker("KIM", 1000));
handler.AddEmployee(new PermanentWorker("LEE", 1500));
// 임시직 등록
TemporaryWorker * alba=new TemporaryWorker("Jung", 700);
alba->AddWorkTime(5); // 5시간 일한결과 등록
handler.AddEmployee(alba);
// 영업직 등록
SalesWorker * seller=new SalesWorker("Hong", 1000, 0.1);
seller->AddSalesResult(7000); // 영업실적 7000
handler.AddEmployee(seller);
// 이번 달에 지불해야 할 급여의 정보
handler.ShowAllSalaryInfo();
// 이번 달에 지불해야 할 급여의 총합
handler.ShowTotalSalary();
return 0;
}
8.3. 가상 소멸자와 참조자의 참조 가능성
- 가상 소멸자 이용하기
#include <iostream>
using namespace std;
class First
{
private:
char * strOne;
public:
First(char * str)
{
strOne=new char[strlen(str)+1];
}
virtual ~First()
{
cout<<"~First()"<<endl;
delete []strOne;
}
};
class Second: public First
{
private:
char * strTwo;
public:
Second(char * str1, char * str2) : First(str1)
{
strTwo=new char[strlen(str2)+1];
}
virtual ~Second()
{
cout<<"~Second()"<<endl;
delete []strTwo;
}
};
int main(void)
{
First * ptr=new Second("simple", "complex");
delete ptr;
return 0;
}
- 가상함수를 이용하여 override한 함수 호출하기(참조자)
#include <iostream>
using namespace std;
class First
{
public:
void FirstFunc()
{
cout<<"FirstFunc()"<<endl;
}
virtual void SimpleFunc()
{
cout<<"First's SimpleFunc()"<<endl;
}
};
class Second: public First
{
public:
void SecondFunc()
{
cout<<"SecondFunc()"<<endl;
}
virtual void SimpleFunc()
{
cout<<"Second's SimpleFunc()"<<endl;
}
};
class Third: public Second
{
public:
void ThirdFunc()
{
cout<<"ThirdFunc()"<<endl;
}
virtual void SimpleFunc()
{
cout<<"Third's SimpleFunc()"<<endl;
}
};
int main(void)
{
Third obj;
obj.FirstFunc();
obj.SecondFunc();
obj.ThirdFunc();
obj.SimpleFunc();
Second & sref=obj;
sref.FirstFunc();
sref.SecondFunc();
sref.SimpleFunc();
First & fref=obj;
fref.FirstFunc();
fref.SimpleFunc();
return 0;
}