8장상속 - contents.kocw.or.krcontents.kocw.or.kr/document/cpp08_inheritance.pdf ·...
TRANSCRIPT
C++ 프 그래 문
8 상
상 본 개
상 문제 제
base 클래스 접근 제어 protected
상 계에 생
함수 정 (function overriding)
폴트 액 스 정 조체
derived 클래스 상
다 상
virtual base 클래스
derived 클래스 폴트 복사 생 폴트 연산
private 생 사
8 상 1
1. 상 본 개
다 과 같 문제를 한 클래스 계
n 동차
Ø : 색상, 량, 현
Ø 드 : 가 하라, 춰라, 시동 켜라
n 트럭
Ø : 색상, 량, 현 , 최 량
Ø 드 : 가 하라, 춰라, 시동 켜라
n 택시
Ø : 색상, 량, 현 , , 주행거리
Ø 드 : 가 하라, 춰라, 시동 켜라
1 : 동차 클래스(CCar) 트럭과 택시를 현
class CCar {
:
색상, 배기량, 현재 , 최 량, 금, 주행거리;
메 드 :
가 하라, 멈춰라, 시동을켜라;
};
문제점 : 실제 객체가 트럭 라
과 주행거리는 필 .
실제 객체가 택시라 최 량 필
8 상 2
1. 상 본 개
2 : 동차(CCar), 트럭(CTruck), 택시(CTaxi) 클래스 만들
class CCar {:색상, 배기량, 현재 ;
메 드:가 하라, 멈춰라, 시동을켜라;
};
class CTruck {:색상, 배기량, 현재 , 최 량;
메 드:가 하라, 멈춰라, 시동을켜라;
};
class CTaxi {:색상, 배기량, 현재 , 금, 주행거리;
메 드:가 하라, 멈춰라, 시동을켜라;
};
문제점 : 코드 복
CTruck CCar 동
CTaxi 역시 CCar 동
à 업 비효
코드 복, 비효 제거하는
à상
8 상 3
1. 상 본 개
상 개
n CTruck과 CTaxi 클래스 시
CCar 상 복
내 다시 언 할 필 가 없
n 상 본 문
class CTruck : public CCar {
:
최 량;
메 드:
};
8 상 4
1. 상 본 개
base 클래스 derived 클래스
n base 클래스 : CCar 클래스
n derived 클래스 : CTruck 클래스, CTaxi 클래스
base derived 클래스 계는 상 적 개
n CCar 클래스를 CVehicle 클래스 상 아 만든다
상 계가 연스럽게 립하는 경
n is-a 계 : 트럭 동차 다. 택시는 동차 다. 사과는 과 다.
n 그 에 존 클래스 든 특 상 고 할
상 : 코드 활 한 강 한 수단
8 상 5
2. 상 문제 제
: 원 나타내는 CCircle 클래스
#define PI 3.14
class CCircle {public :
int x, y; // 심double Radius; // 반 름
public :double GetArea() { return (PI * Radius * Radius); } // 면적
};
int main(void){
CCircle Cir;Cir.x = 1; Cir.y = 1; Cir.Radius = 5;
cout << Cir.GetArea() << endl;
return 0;}
편 상 든 는 public에
언
8 상 6
2. 상 문제 제
: 를 나타내는 CSphere 클래스
n 심 (x, y, z), 름(Radius), 적 함수, 피 함수à CCircle 상 !
#define PI 3.14
class CCircle {public :
int x, y; // 심double Radius; // 반 름
public :double GetArea() { return (PI * Radius * Radius); } // 면적
};
class CSphere : public CCircle {// CCircle 터 상public :
int z;public :
double GetVolume() { return ((4.0/3.0) * PI * Radius * Radius * Radius); }};
int main(void){
CSphere Sph;Sph.x = 1; Sph.y = 1; Sph.z = 1; Sph.Radius = 5; // Sph:x, y, Radius 상
cout << " 의 면적 : " << Sph.GetArea() << endl; // Sph:GetArea 상cout << " 의 피 : " << Sph.GetVolume() << endl;return 0;
}
프 그램 문제점 ?
8 상 7
2. 상 문제 제
상 문제 제
1. 액 스 정
ØCCircle 수들 private 역에 포함시킨다 à 에러 생
Ø액 스 정 종류 : public, private, protected
2. 생
Ø base 클래스 derived 클래스에 생 가 필 하다 …
Ø , 호출 , 호출 순
3. CCircle과 CSphere 클래스 GetArea 함수
Ø함수 름 능 동 하 현 차 가 남
ü CCircle : pi * r * r;
ü CSphere : 4 * pi * r * r;
Ø함수 라 !
8 상 8
3. base 클래스 접근 제어 protected
액 스 정 치 종류
액 스 정 public과 private에 한 상 한 접근
base
액 스 정
public private
포함 역 내 접근 포함 역 내 접근
public public O private X
private private O private X
8 상 9
3. base 클래스 접근 제어 protected
다 프 그램 문제점 ?
#define PI 3.14
class CCircle {private : // 멤버 변수를 private으 언
int x, y; // 심double Radius; // 반 름
public :double GetArea() { return (PI * Radius * Radius); }
};
class CSphere : public CCircle {private :
int z;
public :double GetVolume() { return ((4.0/3.0) * PI * Radius * Radius * Radius); }
};
int main(void){
return 0;}
public 상
base 클래스 private
접 접근 허 하 않
8 상 10
3. base 클래스 접근 제어 protected
protected
n 접근 허 하 않 à private과 동
n derived 클래스에 접근 허 à public과 동
액 스 정 에 한 상 한 접근
n protected 포함
주 public 상 사 !
base
액 스정
public protected private
포함 역 내 접근 포함 역 내 접근 포함 역 내 접근
public public O protected O private X
protected protected O protected O private X
private private O private O private X
8 상 11
3. base 클래스 접근 제어 protected
: CCircle 수들 protected 포함
#define PI 3.14
class CCircle {protected : // 멤버 변수를 protected 언
int x, y; // 심double Radius; // 반 름
public :double GetArea() { return (PI * Radius * Radius); }
};
class CSphere : public CCircle {private :
int z;
public :double GetVolume() { return ((4.0/3.0) * PI * Radius * Radius * Radius); }};
int main(void){
CCircle Cir;Cir.x = 5;
return 0;}
에러 : x는 protected à 접근 허 않
8 상 12
#define PI 3.14
class CCircle {protected :
int x, y; // 심double Radius; // 반 름
public :double GetArea() { return (PI * Radius * Radius); }
};
class CSphere : public CCircle {private :
int z;
public :CSphere(int a, int b, int c, double r) // 생 자
{ x = a; y = b; z = c; Radius = r; }double GetVolume() { return ((4.0/3.0) * PI * Radius * Radius * Radius); }
};
int main(void){
CSphere Sph(1, 2, 3, 4);cout << Sph.GetVolume() << endl;
return 0;}
4. 상 계에 생
: CSphere 생 추가
생 : base 클래스 protected에 한 접근 가능
à문제 없 수행
à CCircle 클래스에 생 를 추가한다 ???
8 상 13
4. 상 계에 생
derived 클래스 객체 생 시 리 생 순
n base 클래스 생 à derived 클래스 생
derived 클래스 객체 생 시 생 수행 순
n CCircle 클래스 생 수행à CSphere 클래스 생 수행
n 앞 에 CCircle 클래스 생 는? 폴트 생 !
n CCircle 클래스 생 를 시적 호출하는 ???
à 초 화 문
8 상 14
4. 상 계에 생
: base 클래스 생 호출
#define PI 3.14
class CCircle {protected :
int x, y; // 심double Radius; // 반 름
public :CCircle(int a, int b, double r) : x(a), y(b), Radius(r) { }double GetArea() { return (PI * Radius * Radius); }
};
class CSphere : public CCircle {private :
int z;
public :CSphere(int a, int b, int c, double r) : CCircle(a, b, r), z(c) { }double GetVolume() { return ((4.0/3.0) * PI * Radius * Radius * Radius); }
};
int main(void){
CSphere Sph(1, 2, 3, 4);cout << Sph.GetVolume() << endl;
return 0;}
base 클래스 생 호출
8 상 15
4. 상 계에 생
고 사항
n 다 과 같 초 화 문 사 가
ØCSphere(int a, int b, int c, double r) : x(a), y(b), z(c), Radius(r) { }
Ø아 x, y, Radius 수가 생 전 므 초 화 가능
ü base 클래스 수는 드시 해당(base) 클래스 생 초 화
n 앞 에 다 과 같 초 화는 가능할 ?
ØCSphere(int a, int b, int c, double r) { x = a; y = b; z = c; Radius =
r; }
Ø 생 가 수행 전에 CCircle 생 가 수행 어야만
ü 경 폴트 생 (매개 수가 없는 생 )가 수행
à CCircle 클래스에 폴트 생 가 존 하 않 므 수행 가
8 상 16
4. 상 계에 생
상 계에 호출 순 : 생 역순!
#define PI 3.14
class CCircle {protected :
int x, y; // 심double Radius; // 반 름
public :CCircle(int a, int b, double r) : x(a), y(b), Radius(r) {
cout << "CCircle 생 자" << endl; }~CCircle() { cout << "CCircle 멸자" << endl; }double GetArea() { return (PI * Radius * Radius); }
};
class CSphere : public CCircle {private :
int z;
public :CSphere(int a, int b, int c, double r) : CCircle(a, b, r), z(c) {
cout << "CSphere 생 자" << endl; }~CSphere() { cout << "CSphere 멸자" << endl; }double GetVolume() { return ((4.0/3.0) * PI * Radius * Radius * Radius); }
};
int main(void){
CSphere Sph(1, 1, 1, 1);
cout << Sph.GetArea() << endl;cout << Sph.GetVolume() << endl;
return 0;}
CSphere 객체 하나에
한 호출 주
8 상 17
5. 함수 정
앞 에 CSphere 객체 적(GetArea)에 주
n 적 = 4 * PI * r * r = 12.56
n 에 는 원 적 계산 함수 GetArea를 상 아 사 했 문에
à PI * r * r = 3.14가 나
원 적, 적 하는 함수 GetArea 하
GetArea 함수를 호출하는 객체에 라 신 함수가 수행 하
는
à 함수 정 (function overriding)
int main(void){
CSphere Sph(1, 1, 1, 1);
cout << Sph.GetArea() << endl;cout << Sph.GetVolume() << endl;
return 0;}
8 상 18
// class CCircle 생략
class CSphere : public CCircle {private :
int z;
public :CSphere(int a, int b, int c, double r) : CCircle(a, b, r), z(c) {
cout << "CSphere 생 자" << endl; }~CSphere() { cout << "CSphere 멸자" << endl; }double GetArea() { return (4 * PI * Radius * Radius); } // 함수 재정의double GetVolume() { return ((4.0/3.0) * PI * Radius * Radius * Radius); }
};
int main(void){
CSphere Sph(1, 1, 1, 1);
cout << Sph.GetArea() << endl; // CSphere의 GetArea 함수 호출cout << Sph.GetVolume() << endl;
return 0;}
5. 함수 정
함수 정 를 해 CSphere GetArea 함수 현
CCircle GetArea 함수는 상 는가?
CCircle 객체를 해 만 호출 가능한가?
8 상 19
5. 함수 정
base 클래스(CCircle) GetArea 함수 호출
n CCircle 클래스 GetArea 함수 역시 상
n CSphere 함수에 CCircle GetArea를 호출하는
Ø 다 코드(CSphere 함수 GetArea에 ) 미는?
ü double GetArea() { return (4 * GetArea()); }
ü CSphere 함수 GetArea 호출à 무한 복 호출
Ø CCircle GetArea를 호출하는
ü double GetArea() { return (4 * CCircle::GetArea()); }
ü 정 연산 :: 사
n CSphere 클래스 에 CSphere 객체를 한 함수 호출
Ø CSphere sph;
Ø Sph.CCircle::GetArea(); // CCircle GetArea 함수 호출, :: 사
만약 CShpere 클래스에 int x, y가 언 다
n CCricle x, y 역시 존 함
n CCircle::x, CCircle::y 같 접근 가능
8 상 20
6. 폴트 액 스 정 조체
클래스 조체 차
n public, protected, private 역 없 경 폴트 역
Ø클래스 : private
Ø 조체 : public
n 상 클래스 시 derived 클래스 폴트 액 스 정
Ø derived 클래스가 클래스 경 : private
Ø derived 클래스가 조체 경 : public
Ø base 클래스가 클래스 냐 조체 냐는 무
struct CSphere : CCircle { // derived가 struct이므 폴트 public 상
private :
int z;
public :
CSphere(int a, int b, int c, double r) : CCircle(a, b, r), z(c) { }
double GetVolume() { return ((4.0/3.0) * PI * Radius * Radius * Radius); }
};
다 과 동
struct CSphere : public CCircle
8 상 21
6. 폴트 액 스 정 조체
다 프 그램 문제점 ?#define PI 3.14
class CCircle {protected :
int x, y; // 심double Radius; // 반 름
public :CCircle(int a, int b, double r) : x(a), y(b), Radius(r) { }double GetArea() { return (PI * Radius * Radius); }
};
class CSphere : CCircle {// derived가 class이므 폴트 private 상private :
int z;
public :CSphere(int a, int b, int c, double r) : CCircle(a, b, r), z(c) { }double GetVolume() { return ((4.0/3.0) * PI * Radius * Radius * Radius); }
};
int main(void){
CSphere Sph(1, 1, 1, 1);cout << Sph.GetArea() << endl;cout << Sph.GetVolume() << endl;return 0;
}
8 상 22
7. derived 클래스 상
derived 클래스 상
n 생 호출 순 에 주
class CPoint1 {private :
int x;
protected :int u;
public :CPoint1(int a) : x(a) { cout << "CPoint1 생 자" << endl; }~CPoint1() { cout << "CPoint1 멸자" << endl; }void Print() { cout << "CPoint1" << endl; }
};
class CPoint2 : public CPoint1 {private :
int y;
protected :int v;
public :CPoint2(int a, int b) : CPoint1(a), y(b)
{ cout << "CPoint2 생 자" << endl; }~CPoint2() { cout << "CPoint2 멸자" << endl; }void Print() { cout << "CPoint2" << endl; }
};
8 상 23
7. derived 클래스 상
코드 계
class CPoint3 : public CPoint2 {private :
int z;
protected :int w;
public :CPoint3(int a, int b, int c) : CPoint2(a, b), z(c)
{ cout << "CPoint3 생 자" << endl; }~CPoint3() { cout << "CPoint3 멸자" << endl; }void Print() {
CPoint1::Print(); // CPoint1의 Print 함수 호출CPoint2::Print(); // CPoint2의 Print 함수 호출cout << "CPoint3" << endl;
}};
int main(void){
CPoint3 P3(1, 2, 3);P3.Print();
return 0;}
Print 함수 정
CPoint1, CPoint2 Print 함수
상
8 상 24
8. 다 상
다 상 : 2개 상 클래스 동시에 상 는 경
class CPointX {protected :
int x;int a;
public :CPointX(int a) : x(a) { cout << "CPointX 생 자" << endl; }~CPointX() { cout << "CPointX 멸자" << endl; }void Print() { cout << "CPointX" << endl; }
};
class CPointY {protected :
int y;int a;
public :CPointY(int b) : y(b) { cout << "CPointY 생 자" << endl; }~CPointY() { cout << "CPointY 멸자" << endl; }void Print() { cout << "CPointY" << endl; }
};
8 상 25
8. 다 상
코드 계
class CPointXYZ : public CPointX, public CPointY { // 다 상private :
int z;
public :CPointXYZ(int a, int b, int c) : CPointX(a), CPointY(b), z(c)
{ cout << "CPointXYZ 생 자" << endl; }~CPointXYZ() { cout << "CPointXYZ 멸자" << endl; }void Print() {
// cout << "a : " << a << endl; // 에러발생, 어 a?CPointX::Print(); // CPointX의 Print 함수 호출CPointY::Print(); // CPointY의 Print 함수 호출cout << "CPointXYZ" << endl;
}};
int main(void){
CPointXYZ Pxyz(1, 2, 3);Pxyz.Print();
return 0;}
생 호출 순 : 어느 쪽 를 ?
쪽(클래스 언 시 시 시 순 )
호 문제 생
CPointX::a, CPointY::a 같 사
8 상 26
9. virtual base 클래스
다 상 고 사항
class CPointX {protected :
int x;
public :CPointX(int a) : x(a) { cout << "CPointX 생 자" << endl; }~CPointX() { cout << "CPointX 멸자" << endl; }void Print() { cout << "CPointX" << endl; }
};
class CPointXY : public CPointX {protected :
int y;
public :CPointXY(int a, int b) : CPointX(a), y(b)
{ cout << "CPointXY 생 자" << endl; }~CPointXY() { cout << "CPointXY 멸자" << endl; }void Print() { cout << "CPointXY" << endl; }
};
class CPointXZ : public CPointX {protected :
int z;
public :CPointXZ(int a, int c) : CPointX(a), z(c)
{ cout << "CPointXZ 생 자" << endl; }~CPointXZ() { cout << "CPointXZ 멸자" << endl; }void Print() { cout << "CPointXZ" << endl; }
};
8 상 27
9. virtual base 클래스
코드 계
class CPointXYZ : public CPointXY, public CPointXZ {private :
int xyz;
public :CPointXYZ(int a, int b, int c) : CPointXY(a, b), CPointXZ(a, c), xyz(0)
{ cout << "CPointXYZ 생 자" << endl; }~CPointXYZ() { cout << "CPointXYZ 멸자" << endl; }void Print() {
// cout << "x : " << x << endl; // 에러발생, 어 x?CPointX::Print(); // VC++ 6.0에 는 에러 발생CPointXY::Print();CPointXZ::Print();cout << "CPointXYZ" << endl;
}};
int main(void){
CPointXYZ Pxyz(1, 2, 3);Pxyz.Print();
return 0;}
호 문제 생
x 2개, y 1개, z 1개 존
CPointX 단 한 만
상 는
à virtual base 클래스 정
class CPointXY : virtual public CPointX { ... }
class CPointXZ : virtual public CPointX { ... }
수정 후 출 결과를 비 해 보라. ( 폴트 생 자 필수)
8 상 28
10. derived 클래스 폴트 복사 생 폴트 연산
폴트 복사 생 폴트 연산 본 동 식
n 단 복사
derived 클래스 폴트 복사 생 폴트 연산
n 단 복사?
n 다 과 같 단 복사를 수행하는 복사 생 문제점 ?
class CPoint {
private :
int x, y;
public :
CPoint(const CPoint &Po) { x = Po.x; y = Po.y; } // 복사 생 자
CPoint &operator=(const CPoint &Po) // 입 연산자
{ x = Po.x; y = Po.y; return (*this); }
};
class CPoint3 : public CPoint {
CPoint3(const CPoint3 &Po) { x = Po.x; y = Po.y; z = Po.z; }
}x 접근 가 : CPoint private !
8 상 29
10. derived 클래스 폴트 복사 생 폴트 연산
derived 클래스 폴트 복사 생 폴트 연산 동
n 단 복사
n base 클래스 복사 생 연산 호출
n 만약, base 클래스 복사 생 연산 를 private 시
적 하고, derived 클래스에 는 시적 하 않는다 ?
Ø base 객체 derived 객체에 한 복사 생 연산 가
class CPoint3 :public CPoint {
private :
int z;
public :
CPoint3(const CPoint3 &Po) : CPoint(Po) { z = Po.z; }
CPoint3 &operator=(const CPoint3 &Po) {
CPoint::operator=(Po); z = Po.z;
return (*this);
}
};
8 상 30
11. private 생 사
다 프 그램 문제점 ?
생 를 private 역에 치시키는 경 ?
class CPoint {private :
int x, y;CPoint(int a, int b) : x(a), y(b) { } // 생 자, private 멤버임
public :void Print() { cout << "(" << x << ", " << y << ")" << endl; }
};
int main(void){
CPoint P1(3, 4);P1.Print();
return 0;}
private 역에 는 생 호출 가à에러 생
8 상 31
11. private 생 사
private 생 사
n 프 그램 전체적 한 객체 생 사
class CPoint {private :
int x, y;CPoint(int a, int b) : x(a), y(b) { }~CPoint() { if (OnlyPoint != NULL) delete OnlyPoint; }static CPoint *OnlyPoint; // 유일한 CPoint 객체를 가리킬 포인터
public :static CPoint *GetPoint() { // OnlyPoint를 반환하는 함수
if (OnlyPoint == NULL) // 최초 수행 시 객체 생OnlyPoint = new CPoint(3, 4);
return OnlyPoint;}void Print() { cout << "(" << x << ", " << y << ")" << endl; }
};
CPoint *CPoint::OnlyPoint = NULL; // 초기화, 아 객체 생 전
int main(void){
CPoint::GetPoint()->Print();return 0;
}
패 : 복적 생하는문제에 한
해 연
: Singleton 패 – 객체가 하나만 존
à C++과는 개 주제