상속(inheritance)
Programming/C++ 2012. 6. 6. 20:19 |상속은 적용이 중요한 문법이다. 적절할 때 선별적으로 적용할 수 있어야 한다.
#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;
}
'Programming > C++' 카테고리의 다른 글
상속을 위한 조건 (0) | 2012.06.19 |
---|---|
protected 선언과 세 가지 형태의 상속(public, protected, private) (0) | 2012.06.13 |
C++에서의 static (0) | 2012.05.30 |
friend (0) | 2012.05.26 |
const 객체와 const 객체의 특성 그리고 const 함수 오버로딩 (0) | 2012.05.26 |