HUD(head-up display)
- 조종사가 전방을 향한채 필요한 데이터를 읽을 수 있는 장치
자바는 객체를 물려받는게 1개로 한정(단일 상속)
c++은 객체를 물려받는게 여러개(다중 상속)
다중상속하기 예
1: //다중상속
2: #include <iostream.h>3: #include <stdio.h>4: #include <stdlib.h>5: #include <string.h>
6:7: class audio //클래스8: {9: char *cpMaker; //오디오제조사10:11: public : //내외부 접근가능12: int a;
13: audio() //생성자
14: {15: cpMaker = 0;16: cout << "audio 디폴트생성자" << endl;
17: }18:19: audio(char *cpMaker) //this -> cpMaker가 클래스 cpMaker20: {21: unsigned int uiLen;22:23: this -> cpMaker = 0; //객체자체가 자기자신 가리키는 포인터(this ->)24: uiLen = strlen(cpMaker);25: this -> cpMaker = (char*)malloc(uiLen);26: strcpy(this -> cpMaker, cpMaker); //cpMaker를 객체cpMaker복사27:28: cout << "audio 노디폴트생성자 호출 " << " " << this -> cpMaker << endl;29: }30:31: ~audio()32: {33: if(0 != cpMaker)
34: {35: free(cpMaker);36: }37: cout << "audio 소멸자" << endl;
38:39: }40: };41:42: class car
43: {44: protected : //상속받은애만 사용할수 있음45: int uiSpeed; //속도변수46:47: private : //내부에서만 접근가능속성48: unsigned int uiNumber;49: unsigned char *ucpVendor; //차 제조사50:51: //생성자를 오버로딩
52: public :
53: int c;
54: car() //자료형이 없는 함수(생성자) ,디폴트 생성자
55: {56: uiNumber = 0;57: ucpVendor = 0;58: cout << "car 디폴트생성자 호출" << endl;
59: }60:61: // public : //public을 디폴트 생성자 다음으로 옴겨봄
62: car(unsigned int uiNumber) //디폴트 생성자가 아님63: {64: ucpVendor = 0;65:66: this -> uiNumber = uiNumber;
67: cout << "uiNumber car 생성자 호출 " << uiNumber << endl;
68: }69:70: // public :
71: car(unsigned int uiNumber, char* cpVendor) //디폴트 생성자가 아님72: {73: unsigned int uiLen;74:75: uiLen = strlen(cpVendor);76: ucpVendor = (unsigned char*)malloc(uiLen);77: strcpy((char*)ucpVendor, cpVendor);
78:79: this -> uiNumber = uiNumber;
80: cout << "uiNumber car 생성자 호출 " << this -> uiNumber << " " << cpVendor << endl;81: }82:83: ~car() //틸드붙인거(소멸자)
84: {85: if(0 != ucpVendor)
86: {87: free(ucpVendor);88: }89: cout << "car 소멸자 호출 " << uiNumber << endl;
90: }91:92: };93:94: class audi:public car,public audio //상속(extends 뒤 콤마(,)로 계속 쓸수있는 다중상속)95: {96: public :
97: int k;
98: audi()99: :car(1234, "Germany"),audio("JBL") //인자있는 디폴트생성자100: {101: c = 100; //여기서는 상속받아서 에러가 안일어난다.
102: cout << "audi가 생성되었습니다 " << endl;
103: uiSpeed = 0;104: }105: ~audi()106: {107: cout << "audi가 소멸되었습니다 " << endl;
108: }109:110: void SpeedUp() //속도업111: {112: uiSpeed = uiSpeed + 10;113:114: if(uiSpeed > 100)
115: {116: uiSpeed = 100;117: }118: cout << "지금 속도는 " << uiSpeed << "km/h 입니다" << endl;119: }120:121: void SpeedDown() //속도다운122: {123: uiSpeed = uiSpeed - 10;124:125: if(uiSpeed < 0)
126: {127: uiSpeed = 0;128: }129: cout << "지금 속도는 " << uiSpeed << "km/h 입니다" <<endl;130: }131: };132:133: int main()
134: {135: unsigned char ucVal;136: audi obj;137: obj.k = 100;138: obj.c = 100; //접근불가에러
139: obj.a = 100; //car앞에만 public 에러, public audio 따로 적용(멤버개념)
140: // audio obj1;
141: // audio obj2 = "짝꿍";
142:143: while('q' != ucVal) //q 입력시 종료144: {145: cout << "명령을 입력하시오" << endl;
146: cin >> ucVal; // scanf와 같은 입력기능
147:148: if('u' == ucVal) //u키 입력시149: {150: obj.SpeedUp(); //SpeedUp함수 호출
151: }152:153: else if('d' == ucVal) //d키 입력시154: {155: obj. SpeedDown(); //SpeedDown함수 호출
156: }157:158: }159:160: return 0;
161: }162:
audi : car, audio로 할 시
앞에 있는 클래스가 제일 먼저 생성되며 제일 나중에 소멸된다.
uiNumber car 생성자
audio 디폴트생성자
audi 생성자
audi 소멸자
audio 소멸자
car 소멸자
audi : audio, car로 할 시
audio 디폴트생성자
uiNumber car 생성자
audi 생성자
audi 소멸자
car 소멸자
audio 소멸자
위로 본 결과 순서에 상관이 있다는걸 확인할 수 있다.
derivation – 유도
composition – 구성
상속을 유도라 할 수 있다.
예) 나는 부모님으로부터 유도되었다.(상속)
참고
main함수에서
138: obj.c = 100; //접근불가에러
입력시 에러가 발생하는데
main입장에선 상속을 받을 때 private인지 public인지 결정을 못하는상태?라서 에러가 출력하는것이다.
아래처럼
94: class audi:public car,public audio //상속(extends 뒤 콤마(,)로 계속 쓸수있는 다중상속)
car앞에 public을 입력해주면 main이 결정을 해서 컴파일이 잘된다.
그리고 audio도 마찬가지로 앞에 public을 따로 입력해줘야한다. 이는 멤버개념이라서 그런 것이다.
다중상속에서 test()를 한번 호출해보았다(오버로딩식으로)
1: //다중상속 test()호출
2: #include <iostream.h>3: #include <stdio.h>4: #include <stdlib.h>5: #include <string.h>
6: class audio //클래스7: {8: char *cpMaker; //오디오제조사9: public : //내외부 접근가능10: int a;
11: audio() //생성자
12: {13: cpMaker = 0;14: }15: audio(char *cpMaker) //this -> cpMaker가 클래스 cpMaker16: {17: unsigned int uiLen;18: this -> cpMaker = 0; //객체자체가 자기자신 가리키는 포인터(this ->)19: uiLen = strlen(cpMaker);20: this -> cpMaker = (char*)malloc(uiLen);21: strcpy(this -> cpMaker, cpMaker); //cpMaker를 객체cpMaker복사22: }23: ~audio()24: {25: if(0 != cpMaker)
26: {27: free(cpMaker);28: }29: }30: void test(float)31: {32: cout << "audio test() 호출" << endl;
33: }34: };35: class car
36: {37: protected : //상속받은애만 사용할수 있음38: int uiSpeed; //속도변수39: private : //내부에서만 접근가능속성40: unsigned int uiNumber;41: unsigned char *ucpVendor; //차 제조사42: //생성자를 오버로딩
43: public :
44: int c;
45: car() //자료형이 없는 함수(생성자) ,디폴트 생성자
46: {47: uiNumber = 0;48: ucpVendor = 0;49: }50: car(unsigned int uiNumber) //디폴트 생성자가 아님51: {52: ucpVendor = 0;53: this -> uiNumber = uiNumber;
54: }55: car(unsigned int uiNumber, char* cpVendor) //디폴트 생성자가 아님56: {57: unsigned int uiLen;58: uiLen = strlen(cpVendor);59: ucpVendor = (unsigned char*)malloc(uiLen);60: strcpy((char*)ucpVendor, cpVendor);
61: this -> uiNumber = uiNumber;
62: }63: ~car() //틸드붙인거(소멸자)
64: {65: if(0 != ucpVendor)
66: {67: free(ucpVendor);68: }69: }70: void test(char)71: {72: cout << "car test() 호출" << endl;
73: }74: };75: class audi:public car,public audio //상속(extends 뒤 콤마(,)로 계속 쓸수있는 다중상속)76: {77: public :
78: int k;
79: audi()80: :car(1234, "Germany"),audio("JBL") //인자있는 디폴트생성자81: {82: c = 100; //여기서는 상속받아서 에러가 안일어난다.
83: uiSpeed = 0;84: }85: ~audi()86: {87: }88: void SpeedUp() //속도업89: {90: uiSpeed = uiSpeed + 10;91: if(uiSpeed > 100)
92: {93: uiSpeed = 100;94: }95: }96: void SpeedDown() //속도다운97: {98: uiSpeed = uiSpeed - 10;99: if(uiSpeed < 0)
100: {101: uiSpeed = 0;102: }103: }104: void test(int)105: {106: cout << "audi test() 호출" << endl;
107: }108: };109: int main()
110: {111: unsigned char ucVal;112: audi obj;113: obj.k = 100;114: obj.c = 100; //접근불가에러
115: obj.a = 100; //car앞에만 public 에러, public audio 따로 적용(멤버개념)
116: obj.test('a');117: obj.audio::test(3.55f);118: // c++는변수를 아무곳에서나 쓸 수 있다.
119: audi* p;120: p = &obj;121: p -> test(3); //audi test()호출
122: car* p2;123: p2 = &obj;124: p2 -> test(3); //car test()호출
125: return 0;
126: }127:
116: obj.test('a');
을 입력시 당연히 인자가 char인 car test()를 호출할 것이라 예상했으나..
최근에 호출한 audi test() 호출이 되었다.
car test()를 호출하기 위해서는
obj.car::test(‘a’)를 입력해야 한다.
1: #if 0
2: #include <stdio.h>3: #else
4: #include <iostream.h>5: #endif6: #include <stdlib.h>7: #include <string.h>
8:9: class object
10: {11: // private :
12: public:
13: unsigned char *ucpType;14:15: // public: //object 생성자 호출
16: private :
17: object()18: {19: cout << "object 디폴트생성자" << endl;
20: }21: protected :
22: object(unsigned char *ucpType)23: {24: this -> ucpType = 0;
25: if(0 == ucpType)
26: {27: return;
28: }29:30: strlen((char*)ucpType);
31: this -> ucpType = (unsigned char*)malloc(strlen((char*)ucpType));32: strcpy((char*)this -> ucpType,(char*) ucpType);33: cout << "object 생성자 "<< this -> ucpType << endl;34:35: }36: ~object()37: {38: if(0 != ucpType)
39: {40: free(ucpType);41: }42: cout << "object 소멸자 " << this -> ucpType<< endl;43: }44: };45:46: class human : public object47: {48: public :
49: human()50: :object((unsigned char*)"human")51: {52: cout << "human 디폴트생성자"<< endl;
53: }54: ~human()55: {56: cout << "human 소멸자"<< endl;
57: }58:59: void test()
60: {61: cout << "윤수영" <<endl;
62: }63:64: };65:66: class dog : public object67: {68: public :
69: dog()70: :object((unsigned char*)"dog")71: {72: cout << "dog 디폴트생성자" << endl;
73: }74: ~dog()75: {76: cout << "dog 소멸자" << endl;
77: }78:79: void test()
80: {81: cout << "코커스패니얼" <<endl;
82: }83:84: };85:86: int main()
87: {88: //object obj; //저는 protected 중
89: cout << "-------- human 생성자 호출 ---------" << endl;
90: human man;91: cout << "--------- dog 생성자 호출 ----------" << endl;
92: dog dog1;93: cout << "--------------------------" << endl;
94:95: int iCnt;
96: object *array[] = {&man,&dog1};97: for(iCnt=0; iCnt<2; ++iCnt)
98: {99: cout << array[iCnt] -> ucpType << endl;100: }101:102: cout << "--------------------------" << endl;
103: // k7.test(); //test
104: // k5.test();
105: return 0;
106: }
여기서 중요한 점은 c++은 human따로 dog 따로 자료형을 만들어 줄 필요 없이 자동으로 object로 타입으로 캐스트 된다.
object 포인터를 쓰면 따로 human이나 dog나 포인터를 따로 해 줄 필요가 없다.
c에서는 일일히 다 해줘야하지만 c++은 이런 것이 허용된다.
자바나 MFC등 최상위 클래스는 object이다. (c로 치면 void *와 비슷)
하지만 c++는 그렇지 않다. c를 기반으로 만들어진 언어이기에 object가 최상위라 할 수 없다.
'C 언어 > C++' 카테고리의 다른 글
c++ 기초단계 (11/22) (1) | 2011.11.23 |
---|---|
c++ 기초단계 (11/21) (0) | 2011.11.21 |
c++ 기초단계 (11/18) (0) | 2011.11.18 |
c++ 기초단계 (11/16) (0) | 2011.11.16 |
c++ 기초단계 (11/15) (0) | 2011.11.15 |