중복 멤버의 처리 조 병 규 한 국 교 통 대 학 교 SQ Lab.
멤버의 중복 원인과 처리 className::memberName 부모 클래스로부터 상속이 됨으로써 자식 클래스 내에 동일한 이름의 멤버가 두 개 이상 존재할 수 있음 - 중복된 멤버를 구분하는 방법은 자식 클래스의 고유 멤버는 그대로 사용하고 부모 클래스로부터 상속된 멤버에 대하여는 부모 클래스 이름을 기술하고 ::을 한 다음 멤버 이름을 기술하함 className::memberName SQ Lab.
(예) 중복 멤버의 처리 : 다계층 상속 /*001*/ // overloadingMember01cNcpp /*002*/ /*003*/ #include "iostream" /*004*/ using namespace std; /*005*/ class classG /*006*/ { /*007*/ protected : int y; /*008*/ public : int z; /*009*/ }; /*010*/ class classP : public classG /*011*/ { /*012*/ protected : int y; /*013*/ public : int z; /*014*/ }; /*015*/ class classC : public classP /*016*/ { /*017*/ private : int x; /*018*/ protected : int y; SQ Lab.
/*030*/ void adder(int cp=0, int pp=0, int gp=0) /*031*/ { /*019*/ public : int z; /*020*/ classC() /*021*/ { /*022*/ x = 1; /*023*/ y = 2; /*024*/ z = 3; /*025*/ classP::y = 4; /*026*/ classP::z = 5; /*027*/ classG::y = 6; /*028*/ classG::z = 7; /*029*/ } /*030*/ void adder(int cp=0, int pp=0, int gp=0) /*031*/ { /*032*/ x = x + cp; /*033*/ y = y + cp; /*034*/ z = z + cp; /*035*/ classP::y = classP::y + pp; /*036*/ classP::z = classP::z + pp; /*037*/ classG::y = classG::y + gp; /*038*/ classG::z = classG::z + gp; /*039*/ }; SQ Lab.
/*040*/ void coutMemberData() /*041*/ { /*041*/ { /*042*/ cout << "\n x=>" << x /*043*/ << "\n y=>" << y /*044*/ << "\n z=>" << z; /*045*/ cout << "\n\n classP::y=>" << classP::y /*046*/ << "\n classP::z=>" << classP::z; /*047*/ cout << "\n\n classG::y==>" << classG::y /*048*/ << "\n classG::z==>" << classG::z; /*049*/ } /*050*/ }; /*051*/ /*052*/ void main() /*053*/ { /*054*/ classC Cobject; /*055*/ /*056*/ Cobject.adder(10, 20, 30); /*057*/ Cobject.coutMemberData(); /*058*/ cout << "\n\n----------------------------\n"; /*059*/ SQ Lab.
/*061*/ Cobject.classP::z = 88; /*062*/ Cobject.classG::z = 99; /*060*/ Cobject.z = 77; /*061*/ Cobject.classP::z = 88; /*062*/ Cobject.classG::z = 99; /*063*/ cout << "\n Cobject.z=>" << Cobject.z; /*064*/ cout << "\n Cobject.classP::z=>" << Cobject.classP::z; /*065*/ cout << "\n Cobject.classG::z=>" << Cobject.classG::z; /*066*/ /*067*/ cout << "\n\n\n Type any character : "; /*068*/ cin.get(); /*069*/ } SQ Lab.
classP의 고유 멤버 classG로부터 상속받은 멤버 private : x protected : y y public : z /*005*/ ~ /*009*/ y, z 두 개의 멤버 자료로 구성된 classG를 설정하였다. /*010*/ ~ /*014*/ 자신의 고유 멤버 y, z와 classG에서 상속된 멤버로 구성되는 classP를 설정하였다. 따라서 classP에는 y가 두 개, z가 두 개로 각 각 중복 되어있다. classP의 고유 멤버 classG로부터 상속받은 멤버 private : x protected : y y public : z z SQ Lab.
classC의 고유 멤버 classP로부터 상속받은 멤버 private : x protected : y y /*015*/ ~ /*050*/ 자신의 고유 멤버 x, y, z, classC(), adder(), coutMemberdata()와 classP에서 상속된 멤버로 구성되는 classC를 설정하였다. 따라서 classC에는 y가 세 개, z가 세 개로 각 각 중복 되어있다. classC의 고유 멤버 classP로부터 상속받은 멤버 private : x protected : y y y(classG로부터 상속된 멤버) Public : z classC() adder() coutMemberData() z z(classG로부터 상속된 멤버) SQ Lab.
/*020*/ classC() /*021*/ { /*022*/ x = 1; /*023*/ y = 2; /*024*/ z = 3; x, y, z는 자신(classC)의 고유 멤버이므로 그대로 기술한다. 다음과 자신의 클래스를 나타내어도 된다. classC::x = 1; classC::y = 2; classC::z = 3; /*025*/ classP::y = 4; /*026*/ classP::z = 5; classP로부터 상속받은 y와 z를 지적할 경우에는 앞에 classP::을 기술하여야 한다. /*027*/ classG::y = 6; /*028*/ classG::z = 7; classG로부터 상속받은 y와 z를 지적할 경우에는 앞에 classG::을 기술하여야 한다. /*030*/ ~ /*039*/ adder()멤버 함수를 설정하였다. 자신(classC)의 고유 멤버는 그대로 기술하고, classP로부터 상속받은 멤버를 지적할 경우에는 classP::을, classG로부터 상속받은 멤버를 지적할 경우에는 classG::을 앞에 기술하여야 한다. /*040*/ ~ /*049*/ coutMemberData()멤버 함수를 설정하였다. SQ Lab.
/*054*/ classC Cobject; classC형태의 객체 Cobject를 생성한다. /*060*/ Cobject.z = 77; Cobject의 자신의 고유 멤버 z에 77을 수록한다. /*061*/ Cobject.classP::z = 88; Cobject의 classP로부터 상속된 멤버 z에 88을 수록한다. /*062*/ Cobject.classG::z = 99; Cobject의 classG로부터 상속된 멤버 z에 99를 수록한다. /*063*/ cout << "\n Cobject.z=>" << Cobject.z; Cobject의 자신의 고유 멤버 z 값을 화면에 나타낸다. /*064*/ cout << "\n Cobject.classP::z=>" << Cobject.classP::z; Cobject의 classP로부터 상속된 멤버 z 값을 화면에 나타낸다. /*065*/ cout << "\n Cobject.classG::z=>" << Cobject.classG::z; Cobject의 classG로부터 상속된 멤버 z 값을 화면에 나타낸다. SQ Lab.
(예) 중복 명칭 : 다중 부모 상속 /*001*/ // overloadingMember02cNcpp /*002*/ /*003*/ #include "iostream" /*004*/ using namespace std; /*005*/ class classF /*006*/ { /*007*/ protected : int y; /*008*/ public : int z; /*009*/ }; /*010*/ /*011*/ class classM /*012*/ { /*013*/ protected : int y; /*014*/ public : int z; /*015*/ }; /*016*/ SQ Lab.
/*017*/ class classC : public classF, public classM /*018*/ { /*018*/ { /*019*/ private : int x; /*020*/ protected : int y; /*021*/ public : int z; /*022*/ /*023*/ classC() /*024*/ { /*025*/ x = 1; /*026*/ y = 2; /*027*/ z = 3; /*028*/ classF::y = 4; /*029*/ classF::z = 5; /*030*/ classM::y = 6; /*031*/ classM::z = 7; /*032*/ } SQ Lab.
/*033*/ void adder(int cp=0, int fp=0, int mp=0) /*034*/ { /*034*/ { /*035*/ x = x + cp; /*036*/ y = y + cp; /*037*/ z = z + cp; /*038*/ classF::y = classF::y + fp; /*039*/ classF::z = classF::z + fp; /*040*/ classM::y = classM::y + mp; /*041*/ classM::z = classM::z + mp; /*042*/ }; /*043*/ void coutMemberData() /*044*/ { /*045*/ cout << "\n x=>" << x /*046*/ << "\n y=>" << y /*047*/ << "\n z=>" << z; /*048*/ cout << "\n\n classF::y=>" << classF::y /*049*/ << "\n classF::z=>" << classF::z; /*050*/ cout << "\n\n classM::y=>" << classM::y /*051*/ << "\n classM::z=>" << classM::z; /*052*/ } /*053*/ }; SQ Lab.
/*059*/ Cobject.coutMemberData(); /*054*/ void main() /*055*/ { /*056*/ classC Cobject; /*057*/ /*058*/ Cobject.adder(10, 20, 30); /*059*/ Cobject.coutMemberData(); /*060*/ cout <<" \n\n----------------------------\n"; /*061*/ /*062*/ Cobject.z = 111; /*063*/ Cobject.classF::z = 333; /*064*/ Cobject.classM::z = 555; /*065*/ /*066*/ cout << "\n Cobject.z=>" << Cobject.z; /*067*/ cout << "\n Cobject.classF::z=>" << Cobject.classF::z; /*068*/ cout << "\n Cobject.classM::z=>" << Cobject.classM::z; /*069*/ /*070*/ cout << "\n\n\n ype any character : "; /*071*/ cin.get(); /*072*/ } SQ Lab.
classC의 고유 멤버 classF로부터 상속받은 멤버 classM으로부터 private : x protected : y y /*005*/ ~ /*009*/ y, z 두 개의 멤버 자료로 구성된 classF를 설정하였다. /*011*/ ~ /*015*/ y, z 두 개의 멤버 자료로 구성된 classM를 설정하였다. /*017*/ ~ /*053*/ 자신의 고유 멤버 x, y, z, classC(), adder(), coutMemberdata()와 classF에서 상속된 멤버와 classM에서 상속된 멤버로 구성되는 classC를 설정하였다. 따라서 classC에는 y가 세 개, z가 세 개로 각 각 중복 되어있다. classC의 고유 멤버 classF로부터 상속받은 멤버 classM으로부터 private : x protected : y y Public : z classC() adder() coutMemberData() z SQ Lab.
/*023*/ classC() /*024*/ { /*025*/ x = 1; /*026*/ y = 2; /*027*/ z = 3; x, y, z는 자신(classC)의 고유 멤버이므로 그대로 기술한다. 다음과 자신의 클래스를 나타내어도 된다. classC::x = 1; classC::y = 2; classC::z = 3; /*028*/ classF::y = 4; /*029*/ classF::z = 5; classF로부터 상속받은 y와 z를 지적할 경우에는 앞에 classF::을 기술하여야 한다. /*030*/ classM::y = 6; /*031*/ classM::z = 7; classM으로부터 상속받은 y와 z를 지적할 경우에는 앞에 classM::을 기술하여야 한다. /*033*/ ~ /*042*/ adder()멤버 함수를 설정하였다. 자신(classC)의 고유 멤버는 그대로 기술하고, classF로부터 상속받은 멤버를 지적할 경우에는 classF::을, classM으로부터 상속받은 멤버를 지적할 경우에는 classM::을 앞에 기술하여야 한다. /*043*/ ~ /*052*/ coutMemberData()멤버 함수를 설정하였다. SQ Lab.
/*056*/ classC Cobject; classC형태의 객체 Cobject를 생성한다. /*062*/ Cobject.z = 111; Cobject의 자신의 고유 멤버 z에 111을 수록한다. /*063*/ Cobject.classF::z = 333; Cobject의 classF로부터 상속된 멤버 z에 333을 수록한다. /*064*/ Cobject.classM::z = 555; Cobject의 classM으로부터 상속된 멤버 z에 555를 수록한다. /*066*/ cout << "\n Cobject.z=>" << Cobject.z; Cobject의 자신의 고유 멤버 z 값을 화면에 나타낸다. /*067*/ cout << "\n Cobject.classF::z=>" << Cobject.classF::z; Cobject의 classF로부터 상속된 멤버 z 값을 화면에 나타낸다. /*068*/ cout << "\n Cobject.classM::z=>" << Cobject.classM::z; Cobject의 classM으로부터 상속된 멤버 z 값을 화면에 나타낸다. SQ Lab.
상속 관계에 virtual 선언 class subclassName : virtual [accessMode] parentClassName 상속 관계에 virtual을 선언 하면 부모 클래스의 같은 멤버가 상속될 경우 하나만을 상속한다. 동일한 멤버가 있는 부모 클래스는 모두 virtual로 선언해야 하며, 하나라도 선언을 해 주지 않으면 효력이 없어진다. SQ Lab.
(예) 중복 명칭 : 다중 부모 상속 /*001*/ // overloadingMemberVirtual01cNcpp /*002*/ /*003*/ #include "iostream" /*004*/ using namespace std; /*005*/ class classG /*006*/ { /*007*/ public : int gx; /*008*/ }; /*009*/ class classF : virtual public classG /*010*/ { /*011*/ public: int x; /*012*/ }; /*013*/ class classM : virtual public classG /*014*/ { /*015*/ public: int x; /*016*/ }; /*017*/ class classC : public classF, public classM /*018*/ { /*019*/ public: int x; SQ Lab.
/*027*/ void adder(int cp=0, int fp=0, int mp=0, int gp=0) /*028*/ { /*020*/ classC() /*021*/ { /*022*/ x = 1; /*023*/ classF::x = 3; /*024*/ classM::x = 5; /*025*/ gx = 7; /*026*/ } /*027*/ void adder(int cp=0, int fp=0, int mp=0, int gp=0) /*028*/ { /*029*/ x = x + cp; /*030*/ classF::x = classF::x + fp; /*031*/ classM::x = classM::x + mp; /*032*/ gx = gx + gp; /*033*/ }; /*034*/ void coutMemberData() /*035*/ { /*036*/ cout << "\n gx=========>" << gx /*037*/ << "\n classF::gx=>" << classF::gx /*038*/ << "\n classM::gx=>" << classM::gx; /*039*/ } /*040*/ }; SQ Lab.
/*046*/ Cobject.coutMemberData(); /*041*/ void main() /*042*/ { /*043*/ classC Cobject; /*044*/ /*045*/ Cobject.adder(10, 30, 50, 70); /*046*/ Cobject.coutMemberData(); /*047*/ cout << "\n\n----------------------------\n"; /*048*/ /*049*/ Cobject.gx = 99; /*050*/ cout << "\n Cobject.gx=========>" << Cobject.gx; /*051*/ cout << "\n Cobject.classF::gx=>" << Cobject.classF::gx; /*052*/ cout << "\n Cobject.classM::gx=>" << Cobject.classM::gx; /*053*/ /*054*/ cout << "\n\n\n Type any character : "; /*055*/ cin.get(); /*056*/ } SQ Lab.
classF의 고유 멤버 classG로부터 상속받은 멤버 private : protected public : x gx /*005*/ ~ /*008*/ gx 한개 개의 멤버 자료로 구성된 classG를 설정하였다. /*009*/ ~ /*012*/ 자신의 고유 멤버 x와 classG로부터 virtual public으로 상속된 멤버로 구성된 classF를 설정하였다. classF의 고유 멤버 classG로부터 상속받은 멤버 private : protected public : x gx /*013*/ ~ /*016*/ 자신의 고유 멤버 x와 classG로부터 virtual public으로 상속된 멤버로 구성된 classM을 설정하였다. classM의 고유 멤버 classG로부터 상속받은 멤버 private : protected public : x gx SQ Lab.
classC의 고유 멤버 classF로부터 상속받은 멤버 private : protected Public : x /*017*/ ~ /*040*/ 자신의 고유 멤버 x, classC(), adder(), coutMemberData()와 classF와 classM으로부터 public으로 상속된 멤버로 구성된 classC를 설정하였다. 부모 클래스에서 classG로부터 상속받을 때 virtual을 선언하였으므로 gx는 하나만 상속된다. classC의 고유 멤버 classF로부터 상속받은 멤버 private : protected Public : x classC() adder() coutMemberData() x gx <========> gx SQ Lab.
/*020*/ classC() /*021*/ { /*022*/ x = 1; x는 자신(classC)의 고유 멤버이므로 그대로 기술한다. 다음과 자신의 클래스를 나타내어도 된다. classC::x = 1; /*023*/ classF::x = 3; classF로부터 상속받은 x를 지적할 경우에는 앞에 classF::을 기술하여야 한다. /*024*/ classM::x = 5; classM으로부터 상속받은 x를 지적할 경우에는 앞에 classM::을 기술하여야 한다. /*025*/ gx = 7; classF의 gx와 classM의 gx는 동일한 멤버이다. 따라서 구분을 하지 않아도 되며 다음과 같이 표현하여도 된다. classF::gx = 7; classM::gx = 7; /*027*/ ~ /*033*/ adder()멤버 함수를 설정하였다. 자신(classC)의 고유 멤버는 그대로 기술하고, classF로부터 상속받은 멤버를 지적할 경우에는 classF::을, classM으로부터 상속받은 멤버를 지적할 경우에는 classM::을 앞에 기술하며, gx는 어느 부모 클래스를 기술하여도 되고 생략해도 된다. /*034*/ ~ /*039*/ coutMemberData()멤버 함수를 설정하였다. gx, classF::gx, classM::gx는 모두 동일한 멤버를 지적한다. SQ Lab.
/*043*/ classC Cobject; classC형태의 객체 Cobject를 생성한다. /*049*/ Cobject.gx = 99; Cobject의 gx에 99를 수록한다. /*050*/ cout << "\n Cobject.gx=========>" << Cobject.gx; /*051*/ cout << "\n Cobject.classF::gx=>" << Cobject.classF::gx; /*052*/ cout << "\n Cobject.classM::gx=>" << Cobject.classM::gx; Cobject의 gx, classF::gx, classM::gx는 모두 동일한 멤버를 지적한다. SQ Lab.
[실습문제] [실습문제 1] 다계층 및 다중 부모 /*001*/ // practice1301cNcpp /*002*/ 다음 프로그램을 해석하여 화면의 출력 결과를 나타내시오. /*001*/ // practice1301cNcpp /*002*/ /*003*/ #include "iostream" /*004*/ using namespace std; /*005*/ class classG /*006*/ { /*007*/ public: int gx; /*008*/ }; /*009*/ class classF : public classG /*010*/ { /*011*/ public: int x; /*012*/ }; SQ Lab.
/*013*/ class classM : public classG /*014*/ { /*015*/ public : int x; /*014*/ { /*015*/ public : int x; /*016*/ }; /*017*/ class classC : public classF, public classM /*018*/ { /*019*/ public : int x; /*020*/ classC() /*021*/ { /*022*/ x = 1; /*023*/ classF::x = 3; /*024*/ classM::x = 5; /*025*/ classF::gx = 7; /*026*/ classM::gx = 9; /*027*/ } /*028*/ void adder(int cp=0, int fp=0, int mp=0, int gp=0) /*029*/ { /*030*/ x = x + cp; /*031*/ classF::x = classF::x + fp; /*032*/ classM::x = classM::x + mp; /*033*/ classF::gx = classF::gx + gp; /*034*/ classM::gx = classM::gx + gp; /*035*/ }; SQ Lab.
/*036*/ void coutMemberData() /*037*/ { /*037*/ { /*038*/ cout << "\n x==========>" << x /*039*/ << "\n classF::x==>" << classF::x /*040*/ << "\n classM::x==>" << classM::x /*041*/ << "\n classF::gx=>" << classF::gx /*042*/ << "\n classM::gx=>" << classM::gx; /*043*/ } /*044*/ }; /*045*/ void main() /*046*/ { /*047*/ classC Cobject; /*048*/ /*049*/ Cobject.adder(10, 30, 50, 70); /*050*/ Cobject.coutMemberData(); /*051*/ cout << "\n\n-----------------------------\n"; /*052*/ /*053*/ Cobject.classF::gx = 111; /*054*/ Cobject.classM::gx = 333; /*055*/ cout << "\n Cobject.classF::gx=>" << Cobject.classF::gx; /*056*/ cout << "\n Cobject.classM::gx=>" << Cobject.classM::gx; /*057*/ SQ Lab.
/*058*/ cout << "\n\n\n Type any character : "; /*059*/ cin.get(); /*060*/ } SQ Lab.