서브클래스 조 병 규 한 국 교 통 대 학 교 SQ Lab.
subclass 상속(계승 : inheritance) 재사용(reuse) - 자신만의 독특한 특성(멤버)를 가지고 있으며, - 이미 존재하는 클래스의 전체 혹은 부분적인 멤버들을 상속받아 구성시킨 클래스 상속(계승 : inheritance) - 기존 클래스의 특성(멤버)을 사용할 수 있도록 이어 받는 것 재사용(reuse) 이미 만들어진 클래스의 멤버를 서브 클래스에서 상속받아 멤버로 구성시킬 경우 서브 클래스에서 기존 클래스의 멤버를 재사용(reuse)하는 것임 재사용 되는 멤버들은 오랜 시간 사용됨으로써 많은 부분 에러가 수정되어 에러의 발생률이 낮아 신뢰성(reliability)이 높다고 할 수 있으며, 또한 멤버들을 재사용하는 것은 새롭게 만들어 사용하는 것에 비해 소프트웨어 개발 생산성(productivity)을 높일 수 있는 장점이 있음 SQ Lab.
클래스들의 관계 SQ Lab. cjnu
- 시스템 혹은 프로그램을 구성하는 클래스들의 상호 관계는 계층적 관계(hierarchical relation)로서 이를 도식화해 보면 나무 구조로 표현될 수 있다. 따라서 클래스의 관계에 따른 명칭을 부여할 수 있으며 이는 상대적인 것이다. ① 기본 클래스(base class) : 모든 서브클래스들이 공통으로 사용할 수 있는 멤버들로 구성된 가장 기본 또는 중심이 되는 클래스이다. ② 부모 클래스(parent class, super class, father class) : 자식 클래스(child class, subclass)에 멤버를 상속시켜 주는 클래스이다. ③ 자식 클래스(child class, son class) : 자신만의 독특한 특성(멤버)을 가지며, 부모 클래스(parent class)로부터 상속된 멤버로 구성된 클래스이다. ④ 조상 클래스(ancestor class) : 부모 클래스들의 집합을 말한다. ⑤ 자손 클래스(descendant class) : 자식 클래스들의 집합을 말한다. ⑥ 형제 클래스(siblings class) : 같은 부모를 가지고 있는 클래스들이다. SQ Lab.
서브클래스의 설정 class subclassName : [accessMode] parentClassName { 서브클래스 자신의 고유 멤버(들) }; - accessMode : 상속 관계 설정 부모 클래스의 어떠한 멤버들을 상속 받을 것인 가를 설정(생략하면 private) - 자신의 고유 멤버(들)과 지정한 부모 클래스로부터 상속받은 멤버들로 구성된다. SQ Lab.
[상속 관계 표(inheritance relation table)] 부모 클래스 상속관계 private 멤버 protected public 상속안됨 SQ Lab.
(예) 상속 (access mode : public) /*001*/ // inheritancePublic01cNcpp /*002*/ /*003*/ #include "iostream" /*004*/ using namespace std; /*005*/ class classP /*006*/ { /*007*/ private : int p1; /*008*/ protected : int p2; /*009*/ public : int p3; /*010*/ }; /*011*/ /*012*/ class classC : public classP /*013*/ { /*014*/ private : int c1; /*015*/ protected: I nt c2; /*016*/ public : int c3; SQ Lab.
/*022*/ p1 = 4; // error : no member /*023*/ p2 = 5; /*024*/ p3 = 6; /*017*/ classC() /*018*/ { /*019*/ c1 = 1; /*020*/ c2 = 2; /*021*/ c3 = 3; /*022*/ p1 = 4; // error : no member /*023*/ p2 = 5; /*024*/ p3 = 6; /*025*/ } /*026*/ void coutMemberData() /*027*/ { /*028*/ cout << "\n\n c1=>" << c1; /*029*/ cout << "\n c2=>" << c2; /*030*/ cout << "\n c3=>" << c3; /*031*/ cout << "\n\n p1=>" << p1; // error : no member /*032*/ cout << "\n\n p2=>" << p2; /*033*/ cout << "\n p3=>" << p3; /*034*/ } /*035*/ }; SQ Lab.
/*040*/ Cobject1.c1 = 100; // error : private member /*036*/ void main() /*037*/ { /*038*/ classC Cobject1; /*039*/ /*040*/ Cobject1.c1 = 100; // error : private member /*041*/ Cobject1.c2 = 200; // error : protected member /*042*/ Cobject1.c3 = 300; /*043*/ Cobject1.p1 = 400; // error : no member /*044*/ Cobject1.p2 = 500; // error : protected member /*045*/ Cobject1.p3 = 600; /*046*/ /*047*/ cout << "\n\n c1=>" << Cobject1.c1; // error : private member /*048*/ cout << "\n\n c2=>" << Cobject1.c2; // error : protected member /*049*/ cout << "\n\n c3=>" << Cobject1.c3; /*050*/ cout << "\n\n p1=>" << Cobject1.p1; // error : no member /*051*/ cout << "\n\n p2=>" << Cobject1.p2; // error : protected member /*052*/ cout << "\n\n p3=>" << Cobject1.p3; /*053*/ /*054*/ Cobject1.coutMemberData(); /*055*/ /*056*/ cout << "\n\n Type any character : "; /*057*/ cin.get(); /*058*/ } SQ Lab.
classP의 고유 멤버 private : p1 protected : p2 public : p3 classC의 고유 멤버 /*005*/ ~ /*010*/ classP를 설정하였다. classP의 고유 멤버 private : p1 protected : p2 public : p3 /*012*/ ~ /*035*/ classC를 설정하였다. 자신의 고유 멤버와 classP로부터 public 관계로 상속된 멤버로 멤버 들이 구성된다. classC의 고유 멤버 classP로부터 상속된 멤버 private : c1 protected : c2 p2 Public : c3 classC() coutMemberData() p3 SQ Lab.
/*017*/ ~ /*025*/ classC의 생성자를 설정한다. /*022*/ p1 = 4; // error : no member p1은 classP로부터 상속되지 않아 classC의 멤버 자료가 아니다. 따라서 사용할 수 없다. /*026*/ ~ /*034*/ coutMemberData() 멤버 함수를 설정한다. /*031*/ cout << "\n\n p1=>" << p1; // error : no member /*038*/ classC Cobject1; classC형태의 객체 Cobject1을 생성한다. /*040*/ Cobject1.c1 = 100; // error : private member Cobject의 c1은 private 멤버이기 때문에 외부에서 사용(접근)할 수 없다. /*041*/ Cobject1.c2 = 200; // error : protected member Cobject의 c2는 protected 멤버이기 때문에 외부에서 사용(접근)할 수 없다. /*043*/ Cobject1.p1 = 400; // error : no member Cobject의 p1은 classC의 멤버가 아니기 때문에 사용(접근)할 수 없다. /*044*/ Cobject1.p2 = 500; // error : protected member Cobject의 p2는 protected 멤버이기 때문에 외부에서 사용(접근)할 수 없다. SQ Lab.
/. 047. / cout << "\n\n c1=>" << Cobject1 /*047*/ cout << "\n\n c1=>" << Cobject1.c1; // error : private member Cobject의 c1은 private 멤버이기 때문에 외부에서 사용(접근)할 수 없다. /*048*/ cout << "\n\n c2=>" << Cobject1.c2; // error : protected member Cobject의 c2는 protected 멤버이기 때문에 외부에서 사용(접근)할 수 없다. /*050*/ cout << "\n\n p1=>" << Cobject1.p1; // error : no member Cobject의 p1은 classC의 멤버가 아니기 때문에 사용(접근)할 수 없다. /*051*/ cout << "\n\n p2=>" << Cobject1.p2; // error : protected member Cobject의 p2는 protected 멤버이기 때문에 외부에서 사용(접근)할 수 없다. SQ Lab.
(예) 상속 (access mode : private) /*012*/ class classC : private classP classC는 다음과 같이 구성된다. classC의 고유 멤버 classP로부터 상속된 멤버 private : c1 p2, p3 protected : c2 Public : c3 classC() coutMemberData() SQ Lab.
다계층 상속(multi level) 임의의 클래스 멤버(들)를 여러 계층으로 계속 상속시킬 수 있다. 상속되는 멤버들은 바로 위부모 클래스의 멤버들의 소속과 상속 관계의 지정에 따르면 된다. SQ Lab.
(예) 다계층 상속 /*001*/ // inheritanceMultiLevel01cNcpp /*002*/ /*003*/ #include "iostream" /*004*/ using namespace std; /*005*/ class classG /*006*/ { /*007*/ private : int g1; /*008*/ protected : int g2; /*009*/ public : int g3; /*010*/ }; /*011*/ class classP : public classG /*012*/ { /*013*/ private : int p1; /*014*/ protected : int p2; /*015*/ public : int p3; /*016*/ }; SQ Lab.
/*017*/ class classC : public classP /*018*/ { /*018*/ { /*019*/ private : int c1; /*020*/ protected : int c2; /*021*/ public : int c3; /*022*/ classC() /*023*/ { /*024*/ c1 = 1; /*025*/ c2 = 2; /*026*/ c3 = 3; /*027*/ p1 = 4; // error : no member /*028*/ p2 = 5; /*029*/ p3 = 6; /*030*/ g1 = 7; // error : no member /*031*/ g2 = 8; /*032*/ g3 = 9; /*033*/ } SQ Lab.
*034*/ void coutMemberData() /*035*/ { /*035*/ { /*036*/ cout << "\n\n c1=>" << c1; /*037*/ cout << "\n c2=>" << c2; /*038*/ cout << "\n c3=>" << c3; /*039*/ cout << "\n\n p1=>" << p1; // error : no member /*040*/ cout << "\n\n p2=>" << p2; /*041*/ cout << "\n p3=>" << p3; /*042*/ cout << "\n\n g1=>" << g1; // error : no member /*043*/ cout << "\n\n g2=>" << g2; /*044*/ cout << "\n g3=>" << g3; /*045*/ } /*046*/ }; SQ Lab.
/*051*/ Cobject1.c1 = 100; // error : private member /*047*/ void main() /*048*/ { /*049*/ classC Cobject1; /*050*/ /*051*/ Cobject1.c1 = 100; // error : private member /*052*/ Cobject1.c2 = 200; // error : protected member /*053*/ Cobject1.c3 = 300; /*054*/ Cobject1.p1 = 400; // error : no member /*055*/ Cobject1.p2 = 500; // error : protected member /*056*/ Cobject1.p3 = 600; /*057*/ Cobject1.g1 = 700; // error : no member /*058*/ Cobject1.g2 = 800; // error : protected member /*059*/ Cobject1.g3 = 900; /*060*/ /*061*/ cout << "\n\n c1=>" << Cobject1.c1; // error : private member /*062*/ cout << "\n\n c2=>" << Cobject1.c2; // error : protected member /*063*/ cout << "\n\n c3=>" << Cobject1.c3; /*064*/ cout << "\n\n p1=>" << Cobject1.p1; // error : no member /*065*/ cout << "\n\n p2=>" << Cobject1.p2; // error : protected member /*066*/ cout << "\n\n p3=>" << Cobject1.p3; /*067*/ cout << "\n\n g1=>" << Cobject1.g1; // error : no member /*068*/ cout << "\n\n g2=>" << Cobject1.g2; // error : protected member /*069*/ cout << "\n\n g3=>" << Cobject1.g3; SQ Lab.
/*071*/ Cobject1.coutMemberData(); /*072*/ /*070*/ /*071*/ Cobject1.coutMemberData(); /*072*/ /*073*/ cout << "\n\n Type any character : "; /*074*/ cin.get(); /*075*/ } SQ Lab.
classG의 고유 멤버 private : g1 protected : g2 public : g3 classP의 고유 멤버 /*005*/ ~ /*010*/ classG를 설정하였다. classG의 고유 멤버 private : g1 protected : g2 public : g3 /*011*/ ~ /*016*/ classP를 설정하였다. 자신의 고유 멤버와 classG로부터 public 관계로 상속된 멤버로 멤버 들이 구성된다. classP의 고유 멤버 classG로부터 상속된 멤버 private : p1 protected : p2 g2 public : p3 g3 SQ Lab.
classC의 고유 멤버 classP로부터 상속된 멤버 private : c1 protected : c2 p2 g2 /*017*/ ~ /*046*/ classC를 설정하였다. 자신의 고유 멤버와 classP로부터 public 관계로 상속된 멤버로 멤버 들이 구성된다. classC의 고유 멤버 classP로부터 상속된 멤버 private : c1 protected : c2 p2 g2 Public : c3 classC() coutMemberData() p3 g3 SQ Lab.
/*022*/ ~ /*033*/ classC의 생성자를 설정한다. /*027*/ p1 = 4; // error : no member /*030*/ g1 = 7; // error : no member p1과 g1은 classP로부터 상속되지 않아 classC의 멤버 자료가 아니다. 따라서 사용할 수 없다. /*034*/ ~ /*045*/ coutMemberData() 멤버 함수를 설정한다. /*039*/ cout << "\n\n p1=>" << p1; // error : no member /*042*/ cout << "\n\n g1=>" << g1; // error : no member p1과 g1은 classP로부터 상속되지 않아 classC의 멤버 자료가 아니다. 따라서 사용할 수 없다. /*049*/ classC Cobject1; classC형태의 객체 Cobject1을 생성한다. /*051*/ Cobject1.c1 = 100; // error : private member Cobject의 c1은 private 멤버이기 때문에 외부에서 사용(접근)할 수 없다. /*052*/ Cobject1.c2 = 200; // error : protected member Cobject의 c2는 protected 멤버이기 때문에 외부에서 사용(접근)할 수 없다. /*054*/ Cobject1.p1 = 400; // error : no member Cobject의 p1은 classC의 멤버가 아니기 때문에 사용(접근)할 수 없다. /*055*/ Cobject1.p2 = 500; // error : protected member Cobject의 p2는 protected 멤버이기 때문에 외부에서 사용(접근)할 수 없다. SQ Lab.
/*057*/ Cobject1.g1 = 700; // error : no member Cobject의 g1은 classC의 멤버가 아니기 때문에 사용(접근)할 수 없다. /*058*/ Cobject1.g2 = 800; // error : protected member Cobject의 g2는 protected 멤버이기 때문에 외부에서 사용(접근)할 수 없다. /*061*/ cout << "\n\n c1=>" << Cobject1.c1; // error : private member Cobject의 c1은 private 멤버이기 때문에 외부에서 사용(접근)할 수 없다. /*062*/ cout << "\n\n c2=>" << Cobject1.c2; // error : protected member Cobject의 c2는 protected 멤버이기 때문에 외부에서 사용(접근)할 수 없다. /*064*/ cout << "\n\n p1=>" << Cobject1.p1; // error : no member Cobject의 p1은 classC의 멤버가 아니기 때문에 사용(접근)할 수 없다. /*065*/ cout << "\n\n p2=>" << Cobject1.p2; // error : protected member Cobject의 p2는 protected 멤버이기 때문에 외부에서 사용(접근)할 수 없다. /*067*/ cout << "\n\n g1=>" << Cobject1.g1; // error : no member /*068*/ cout << "\n\n g2=>" << Cobject1.g2; // error : protected member SQ Lab.
다중 부모에 의한 상속 (multi parent) class subclassName : [accessMode] parentClassName, [accessMode] parentClassName, ∙ 자식 클래스는 두 개 이상의 부모 클래스로부터도 멤버(들)을 상속받을 수 있다. 부모 클래스 별로 정의된 상속 관계(access mode)에 따라 상속되는 멤버가 결정된다. SQ Lab.
(예) 다중 부모에 의한 상속 /*001*/ // inheritanceMultiParent01cNcpp /*002*/ /*003*/ #include "iostream" /*004*/ using namespace std; /*005*/ class classF /*006*/ { /*007*/ private : int f1; /*008*/ protected : int f2; /*009*/ public : int f3; /*010*/ }; /*011*/ class classM /*012*/ { /*013*/ private : int m1; /*014*/ protected : int m2; /*015*/ public : int m3; /*016*/ }; SQ Lab.
/*017*/ class classC : public classF, public classM /*018*/ { /*018*/ { /*019*/ private : int c1; /*020*/ protected : int c2; /*021*/ public : int c3; /*022*/ classC() /*023*/ { /*024*/ c1 = 1; /*025*/ c2 = 2; /*026*/ c3 = 3; /*027*/ f1 = 4; // error : no member /*028*/ f2 = 5; /*029*/ f3 = 6; /*030*/ m1 = 7; // error : no member /*031*/ m2 = 8; /*032*/ m3 = 9; /*033*/ } SQ Lab.
/*034*/ void coutMemberData() /*035*/ { /*035*/ { /*036*/ cout << "\n\n c1=>" << c1; /*037*/ cout << "\n c2=>" << c2; /*038*/ cout << "\n c3=>" << c3; /*039*/ cout << "\n\n f1=>" << f1; // error : no member /*040*/ cout << "\n\n f2=>" << f2; /*041*/ cout << "\n f3=>" << f3; /*042*/ cout << "\n\n m1=>" << m1; // error : no member /*043*/ cout << "\n\n m2=>" << m2; /*044*/ cout << "\n m3=>" << m3; /*045*/ } /*046*/ }; SQ Lab.
/*051*/ Cobject1.c1 = 100; // error : private member /*047*/ void main() /*048*/ { /*049*/ classC Cobject1; /*050*/ /*051*/ Cobject1.c1 = 100; // error : private member /*052*/ Cobject1.c2 = 200; // error : protected member /*053*/ Cobject1.c3 = 300; /*054*/ Cobject1.f1 = 400; // error : no member /*055*/ Cobject1.f2 = 500; // error : protected member /*056*/ Cobject1.f3 = 600; /*057*/ Cobject1.m1 = 700; // error : no member /*058*/ Cobject1.m2 = 800; // error : protected member /*059*/ Cobject1.m3 = 900; /*060*/ /*061*/ cout << "\n\n c1=>" << Cobject1.c1; // error : private member /*062*/ cout << "\n\n c2=>" << Cobject1.c2; // error : protected member /*063*/ cout << "\n\n c3=>" << Cobject1.c3; /*064*/ cout << "\n\n f1=>" << Cobject1.f1; // error : no member /*065*/ cout << "\n\n f2=>" << Cobject1.f2; // error : protected member /*066*/ cout << "\n\n f3=>" << Cobject1.f3; /*067*/ cout << "\n\n m1=>" << Cobject1.m1; // error : no member /*068*/ cout << "\n\n m2=>" << Cobject1.m2; // error : protected member /*069*/ cout << "\n\n m3=>" << Cobject1.m3; SQ Lab.
/*071*/ Cobject1.coutMemberData(); /*072*/ /*070*/ /*071*/ Cobject1.coutMemberData(); /*072*/ /*073*/ cout << "\n\n Type any character : "; /*074*/ cin.get(); /*075*/ } SQ Lab.
classF의 고유 멤버 private : f1 protected : f2 public : f3 classM의 고유 멤버 /*005*/ ~ /*010*/ classF를 설정하였다. classF의 고유 멤버 private : f1 protected : f2 public : f3 /*011*/ ~ /*016*/ classM를 설정하였다. classM의 고유 멤버 private : m1 protected : m2 public : m3 SQ Lab.
classC의 고유 멤버 classF로부터 상속된 멤버 classM으로부터 private : c1 protected : c2 /*017*/ ~ /*046*/ classC를 설정하였다. 자신의 고유 멤버와 classF로부터 public 관계로, classM으로부터 public 관계로 상속된 멤버들로 구성된다. classC의 고유 멤버 classF로부터 상속된 멤버 classM으로부터 private : c1 protected : c2 f2 m2 public : c3 classC() coutMemberData() f3 m3 SQ Lab.
/*022*/ ~ /*033*/ classC의 생성자를 설정한다. /*027*/ f1 = 4; // error : no member /*030*/ m1 = 7; // error : no member f1과 m1은 classF와 classM으로부터 상속되지 않아 classC의 멤버 자료가 아니다. 따라서 사용할 수 없다. /*034*/ ~ /*045*/ coutMemberData() 멤버 함수를 설정한다. /*039*/ cout << "\n\n f1=>" << f1; // error : no member /*042*/ cout << "\n\n m1=>" << m1; // error : no member /*049*/ classC Cobject1; classC형태의 객체 Cobject1을 생성한다. /*051*/ Cobject1.c1 = 100; // error : private member Cobject의 c1은 private 멤버이기 때문에 외부에서 사용(접근)할 수 없다. /*052*/ Cobject1.c2 = 200; // error : protected member Cobject의 c2는 protected 멤버이기 때문에 외부에서 사용(접근)할 수 없다. /*054*/ Cobject1.f1 = 400; // error : no member Cobject의 f1은 classC의 멤버가 아니기 때문에 사용(접근)할 수 없다. SQ Lab.
/*055*/ Cobject1.f2 = 500; // error : protected member Cobject의 f2는 protected 멤버이기 때문에 외부에서 사용(접근)할 수 없다. /*057*/ Cobject1.m1 = 700; // error : no member Cobject의 m1은 classC의 멤버가 아니기 때문에 사용(접근)할 수 없다. /*058*/ Cobject1.m2 = 800; // error : protected member Cobject의 m2는 protected 멤버이기 때문에 외부에서 사용(접근)할 수 없다. /*061*/ cout << "\n\n c1=>" << Cobject1.c1; // error : private member Cobject의 c1은 private 멤버이기 때문에 외부에서 사용(접근)할 수 없다. /*062*/ cout << "\n\n c2=>" << Cobject1.c2; // error : protected member Cobject의 c2는 protected 멤버이기 때문에 외부에서 사용(접근)할 수 없다. /*064*/ cout << "\n\n f1=>" << Cobject1.f1; // error : no member Cobject의 f1은 classC의 멤버가 아니기 때문에 사용(접근)할 수 없다. /*065*/ cout << "\n\n f2=>" << Cobject1.f2; // error : protected member /*067*/ cout << "\n\n m1=>" << Cobject1.m1; // error : no member /*068*/ cout << "\n\n m2=>" << Cobject1.m2; // error : protected member SQ Lab.
생성자와 파괴자의 실행 순서 부모 클래스와 자식 클래스에 생정자와 파괴자가 존재할 경우 자식 클래스의 객체가 생성 될 때 이들의 실행 순서에 대한 규칙이 있어야 한다. SQ Lab.
생성자의 실행 순서 해당 서브클래스의 객체가 생성될 때 ① 첫 번째 지정한 부모 클래스의 ① 첫 번째 지정한 부모 클래스의 최상위 조상 클래스 생성자부터 차례로 수행하고, ② 두 번째 지정한 부모 클래스의 ∙ ⓝ n 번째 지정한 부모 클래스의 최상위 조상 클래스 생성자부터 차례로 수행한 후 마지막으로 해당 서브클래스의 생성자를 수행한다. SQ Lab.
파괴자의 수행 순서 해당 서브클래스의 객체가 소멸될 때 ① 제일 처음, 해당 서브클래스의 파괴자가 수행되고, ② 마지막에 지정한(n번째) 클래스의 최하위 클래스로부터 최상위 클래스의 순으로파괴자가 수행되고 ∙ ⓜ 두 번째 지정한 클래스의 최하위 클래스로부터 최상위 클래스의 순으로 파괴자가 수행되고 ⓝ 첫 번째 지정한 클래스의 최하위 클래스로부터 최상위 클래스의 순으로 파괴자가 수행된다. SQ Lab.
(예) 생성자, 파괴자 실행 순서 /*001*/ // inheritanceConstructor01cNcpp /*002*/ /*003*/ #include "iostream" /*004*/ using namespace std; /*005*/ class classA1 /*006*/ { /*007*/ public: /*008*/ classA1() {cout << "\n classA1 Constructor";}; /*009*/ ~classA1() { /*010*/ cout << "\n classA1 Destructor"; /*011*/ cout << "\n\n Understand!...(^@^)" /*012*/ << "\n\n Type any character : "; /*013*/ cin.get(); /*014*/ }; /*015*/ }; /*016*/ class classB1 /*017*/ { /*018*/ public: /*019*/ classB1() {cout << "\n classB1 Constructor";}; /*020*/ ~classB1() {cout << "\n classB1 Destructor";}; /*021*/ }; SQ Lab.
/*022*/ class classA2 : public classA1 /*023*/ { /*024*/ public: /*023*/ { /*024*/ public: /*025*/ classA2() {cout << "\n classA2 Constructor";}; /*026*/ ~classA2() {cout << "\n classA2 Destructor";}; /*027*/ }; /*028*/ class classB2 : public classB1 /*029*/ { /*030*/ public: /*031*/ classB2() {cout << "\n classB2 Constructor";}; /*032*/ ~classB2() {cout << "\n classB2 Destructor";}; /*033*/ }; /*034*/ class classC0 : public classA2, public classB2 /*035*/ { /*036*/ public: /*037*/ classC0() {cout << "\n classC0 Constructor";}; /*038*/ ~classC0() {cout << "\n\n classC0 Destructor";}; /*039*/ }; /*040*/ void main() /*041*/ { /*042*/ classC0 c0Object; /*043*/ } SQ Lab.
/*005*/ ~ /*015*/ 생성자와 파괴자만으로 구성된 classA1을 설정하였다. /*016*/ ~ /*021*/ 생성자와 파괴자만으로 구성된 classB1을 설정하였다. /*022*/ ~ /*027*/ classA2 고유의 생성자와 파괴자 그리고 classA1으로부터 public으로 상속받은 생성자와 파괴자로 구성된 classA2를 설정하였다. /*028*/ ~ /*033*/ classB2 고유의 생성자와 파괴자 그리고 classB1으로부터 public으로 상속받은 생성자와 파괴자로 구성된 classB2를 설정하였다. /*024*/ ~ /*039*/ classC0 고유의 생성자와 파괴자 그리고 classA2와 classB2 각 각의 클래스로부터 로 상속받은 생성자와 파괴자로 구성된 classC0을 설정하였다. /*042*/ classC0 c0Object; classC0형태의 객체 c0Object를 생성한다. 이 경우 생성자들은 다음과 같은 순서로 실행된다. classA1() → classA2() → classB1() → classB2() → classC0() /*043*/ } 실행이 종료되기 전 파괴자들이 다음과 같은 순서로 실행된다. ~classC0() → ~classB2() → ~classB1() → ~classA2() → ~classA1() SQ Lab.
[결과] SQ Lab.
부모 클래스 생성자로의 인자 값 전달 childClass생성자(parameterList) : parentClasss생성자(parameterList) [, . . .] { 처리 }; 부모와 자식 클래스의 생성자에 형식 인자가 존재하고, 자식 클래스로 객체를 생성할 때 자식 클래스의 생성자로 전달된 실인자의 값이 부모 클래스의 생성자 인자로도 전달이 된다. - 부모 클래스 생성자의 인자에 전달되는 값은 인자의 순서에 상관없이 같은 이름의 인자에 전달된다. SQ Lab.
(예) 생성자 인자 값 전달 /*001*/ // inheritanceConstructorParameter01cNcpp /*002*/ /*003*/ #include "iostream" /*004*/ using namespace std; /*005*/ class classA1 /*006*/ { /*007*/ public: /*008*/ classA1(int x) /*009*/ { /*010*/ cout << "\n\n classA1::x==>" << x; /*011*/ }; /*012*/ }; /*013*/ class classA2 : classA1 /*014*/ { /*015*/ public: /*016*/ classA2(int x, int y) : classA1(x) /*017*/ { /*018*/ cout << "\n\n classA2::x==>" << x /*019*/ << "\n classA2::y==>" << y; /*020*/ }; /*021*/ }; SQ Lab.
/*022*/ class classA31 : public classA2 /*023*/ { /*024*/ public: /*023*/ { /*024*/ public: /*025*/ classA31(int x, int y, int z) : classA2(x, y) /*026*/ { /*027*/ cout << "\n\n classA31::x=>" << x /*028*/ << "\n classA31::y=>" << y /*029*/ << "\n classA31::z=>" << z; /*030*/ }; /*031*/ }; /*032*/ class classA32 : public classA2 /*033*/ { /*034*/ public: /*035*/ classA32(int x, int y, int z) : classA2(z, x) /*036*/ { /*037*/ cout << "\n\n classA32::x=>" << x /*038*/ << "\n classA32::y=>" << y /*039*/ << "\n classA32::z=>" << z; /*040*/ }; /*041*/ }; SQ Lab.
/*044*/ cout << " classA31 A31object(10, 20, 30);"; /*042*/ void main() /*043*/ { /*044*/ cout << " classA31 A31object(10, 20, 30);"; /*045*/ classA31 A31object(10, 20, 30); /*046*/ /*047*/ cout << "\n------------------------------\n"; /*048*/ /*049*/ cout << " classA32 A32object(10, 20, 30);"; /*050*/ classA32 A32object(10, 20, 30); /*051*/ /*052*/ cout << "\n\n Type any character : "; /*053*/ cin.get(); /*054*/ } SQ Lab.
/*005*/ ~ /*012*/ 정수형 인자를 가지고 있는 생성자만으로 구성된 classA1을 설정하였다. /*013*/ ~ /*021*/ classA1으로부터 상속받고, 정수형 인자 2개를 가지고 있는 생성자만으로 구성된 classA2를 설정하였다. classA2의 객체가 생성될 때 실인자의 값들이 전달되고, 인자 x의 값이 classA1의 인자 x에 전달된다. /*022*/ ~ /*031*/ classA2로부터 상속받고, 정수형 인자 3개를 가지고 있는 생성자만으로 구성된 classA31을 설정하였다. classA31의 객체가 생성될 때 실인자의 값들이 전달되고, 인자 x의 값이 classA2의 첫 번째 인자 x에 전달되고, y의 값이 두 번째 인자 y에 전달된다. /*032*/ ~ /*041*/ classA2로부터 상속받고, 정수형 인자 3개를 가지고 있는 생성자만으로 구성된 classA32를 설정하였다. classA32의 객체가 생성될 때 실인자의 값들이 전달되고, 인자 x의 값이 classA2의 두 번째 인자 x에 전달되고, z의 값이 첫 번째 인자 z에 전달 된다. /*045*/ classA31 A31object(10, 20, 30); classA31형태의 객체 A31object를 생성한다. 실인자를(10, 20, 30)으로 하여 생성자에게 전달하면 A31object 생성자의 인자 x에 10, y에 20, z에 30이 전달되며, 다시 classA2의 생성자 인자 x에 10, y에 20이 전달되고 다시 classA1의 생성자 인자 x에 10이 전달되어 처리된다. 10 20 30 10 20 /*025*/ classA31(int x, int y, int z) : classA2(x, y) 10 20 10 /*016*/ classA2(int x, int y) : classA1(x) SQ Lab.
/*050*/ classA32 A32object(10, 20, 30); 실인자를(10, 20, 30)으로 하여 생성자에게 전달하면 A32object 생성자의 인자 x에 10, y에 20, z에 30이 전달되며, 다시 classA2의 생성자 인자 x에 10, z에 30이 전달되고 다시 classA1의 생성자 인자 x에 30이 전달되어 처리된다. 10 20 30 30 10 /*035*/ classA32(int x, int y, int z) : classA2(z, x) 30 10 30 /*016*/ classA2(int x, int y) : classA1(x) SQ Lab.
[결과] SQ Lab.
[실습문제] [실습문제 1] 상속 다음 프로그램을 해석하여 화면의 출력 결과를 나타내시오. /*001*/ // practice1201cNcpp : inheritance parameter /*002*/ /*003*/ #include "iostream" /*004*/ using namespace std; /*005*/ class classA10 /*006*/ { /*007*/ public: /*008*/ classA10(int x) /*009*/ { /*010*/ cout << "\n\n classA10::x=>" << x; /*011*/ }; /*012*/ }; SQ Lab.
/*013*/ class classA21 : classA10 /*014*/ { /*015*/ public: /*014*/ { /*015*/ public: /*016*/ classA21(int x, int y) : classA10(x) /*017*/ { /*018*/ cout << "\n\n classA21::x=>" << x /*019*/ << "\n classA21::y=>" << y; /*020*/ }; /*021*/ }; /*022*/ class classA22 : classA10 /*023*/ { /*024*/ public: /*025*/ classA22(int x, int y) : classA10(y) /*026*/ { /*027*/ cout << "\n\n classA22::x=>" << x /*028*/ << "\n classA22::y=>" << y; /*029*/ }; /*030*/ }; SQ Lab.
/*031*/ class classA30 : public classA21, public classA22 /*032*/ { /*032*/ { /*033*/ public: /*034*/ classA30(int x, int y, int z) : classA21(x, y), classA22(y, x) /*035*/ { /*036*/ cout << "\n\n classA30::x=>" << x /*037*/ << "\n classA30::y=>" << y /*038*/ << "\n classA30::z=>" << z; /*039*/ }; /*040*/ }; /*041*/ void main() /*042*/ { /*043*/ cout << " classA30 A31object(10, 20, 30);"; /*044*/ classA30 A30object(10, 20, 30); /*045*/ /*046*/ cout << "\n\n Type any character : "; /*047*/ cin.get(); /*048*/ } SQ Lab.