C언어

c++ 공부 요점정리 24

뮹실이 2013. 12. 4. 00:28







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
// ##########################################
//
// 41 상속된 객체와 참조 관계
//
// ##########################################
//
// 객체 레퍼런스
// : 객체를 참조할 수 있는 객체 레퍼런스는
//   클래스 포인터의 특성과 같다.
//
// 클래스 객체의 포인터는 클래스의 객체 뿐만아니라
// 클래스를 상속하고 있는 클래스의 객체도 가리킬있다.
// 
// 다음과 같이 상속관계에 있으면
// 사람 클래스의 포인터를 이용해
// 사람, 학생, 파트타임 객체를 가리킬 수 있다.
// 마찬가지로
// 사람 클래스의 참조도
// 사람, 학생, 파트타임 객체를 가리킬 수 있다.
// 또한 학생 클래스의 참조는
// 학생, 파트타임 객체를 가리킬 수 있다.
// 
#include <iostream>
using std::endl;
using std::cout;

class Person
{
public:
	void Sleep(){ 
		cout<<"Sleep"<<endl;
	}
};

class Student : public Person
{
public:
	void Study(){
		cout<<"Study"<<endl;
	}
};

class PartTimeStd : public Student
{
public:
	void Work(){
		cout<<"Work"<<endl;
	}
};

int main(void)
{
	// 파트타임 클래스는 학생, 사람 클래스를
	// 상속하고 있기 때문에
	PartTimeStd p;
	
	// 학생 클래스의 레퍼런스를 이용해 
	// 파트타임 클래스의 객체를 참조한다.
	Student& ref1=p;
	
	// 사람 클래스의 레퍼런스를 이용해 
	// 파트타임 클래스의 객체를 참조한다.
	Person& ref2=p;
	
	p.Sleep();
	ref1.Sleep();
	ref2.Sleep();

	return 0;
}


// 객체 레퍼런스의 권한
// : 객체를 참조하는 레퍼런스의 권한은
//   클래스 포인터의 권한과 일치
//
//
//
#include <iostream>
using std::endl;
using std::cout;

class Person
{
public:
	void Sleep(){ 
		cout<<"Sleep"<<endl;
	}
};

class Student : public Person
{
public:
	void Study(){
		cout<<"Study"<<endl;
	}
};

class PartTimeStd : public Student
{
public:
	void Work(){
		cout<<"Work"<<endl;
	}
};

int main(void)
{
	PartTimeStd p;
	p.Sleep();
	p.Study();
	p.Work();

	// 사람 클래스의 참조는
	// 학생, 파트타임 객체를 참조할 수 있지만
	// 접근할 수 있는 영역은 사람 클래스의 
	// 내에 선언되어 있거나 사람 클래스가 상속
	// 하고있는 멤버로 제한된다.
	Person& ref=p;
	ref.Sleep();
//	ref.Study(); // Error의 원인
//	ref.Work();  // Error의 원인

	return 0;
}

//
// 오버라이딩(overriding)의 이해
// : 오버라이딩과 오버로딩을 혼돈하지 않도록 주의
// : base 클래스에 선언된 멤버와 같은 형태의
//   멤버를 derived 클래스에서 선언하는것
//   base 클래스의 멤버를 가리는 효과를 가짐
//   보는 시야(pointer)에 따라서 달라지는
//   효과를 가짐
//
#include <iostream>
using std::endl;
using std::cout;

class AAA
{
public:
	void fct(){
		cout<<"AAA"<<endl;
	}
};

class BBB : public AAA
{
public: 
	//AAA 클래스의 fct() 함수를 오버라이딩.
	// aaa 클래스의 fct 함수는
	// bbb 클래스의 fct 함수에 의해서
	// 오버라이딩 되었다.
	void fct(){ 
		cout<<"BBB"<<endl;
	}
};

int main(void)
{
	// b 객체를 생성하면
	// b 객체에는 bbb 클래스의 fct 함수가 있고
	// aaa 클래스의 fct 함수도 있다.
	// 그리고 aaa 클래스의 fct 함수는
	// bbb 클래스의 fct 함수에 의해
	// 오버라이딩 되어있는 상태이다.
	// 즉, 가려진 상태이다.(은닉되어졌다.)
	BBB b;
	
	// 그래서 b 객체의 fct 함수를 호출하면
	// 다음과 같이 호출하면
	// bbb 클래스의 fct 함수가 호출된다.
	// 은닉된 멤버는 보는 시야를 달리하면
	// 볼수도 있다. 다음 예제 참조
	b.fct();

	return 0;
}

//
//
//
#include <iostream>
using std::endl;
using std::cout;

class AAA
{
public:
	void fct(){
		cout<<"AAA"<<endl;
	}
};

class BBB : public AAA
{
public:
	void fct(){
		cout<<"BBB"<<endl;
	}
};

int main(void)
{
	// bbb 클래스의 포인터로 객체 b를 가리키고있다.
	BBB* b=new BBB;
	
	// 포인터가 "보는 시야"에 해당한다.
	// b 객체를 bbb 클래스의 포인터로 가리키면
	// bbb 클래스로 바라보는 것
	// 그렇기 때문에 bbb 클래스의 fct 함수가
	// 호출되고 bbb 클래스의 객체내의 모든
	// 멤버에 접근가능
	b->fct();

	// aaa 클래스의 포인터로 객체 b를 가리키고있다.
	AAA* a=b;
	
	// bbb 클래스의 객체이지만
	// aaa 클래스의 포인터로 가리키면
	// aaa 클래스의 객체로 바라보는 것이기 때문에
	// aaa 클래스의 멤버에만 접근가능하므로
	// aaa 클래스의 fct 함수가 보이게 되어
	// 가려졌던 aaa 클래스의 fct 함수
	// 호출이 가능해진다.
	a->fct();

	delete b;
	return 0;
}

//
// 멤버 함수를 가상(virtual)으로 선언하기
// : 오버라이딩 되는 경우의 특징
//
//
#include <iostream>
using std::endl;
using std::cout;

class AAA
{
public:
	// virtual 키워드가 추가됨
	// 즉, fct 함수를 가상으로 선언하겠다는 의미
	// 없는 함수로 인식하라 라는 의미
	virtual void fct(){
		cout<<"AAA"<<endl;
	}
};

class BBB : public AAA
{
public:
	void fct(){
		cout<<"BBB"<<endl;
	}
};

int main(void)
{
	// bbb 클래스의 포인터로 객체 b를 가리키고있다.
	BBB* b=new BBB;
	b->fct();

	// aaa 클래스의 포인터로 객체 b를 가리키고있다.
	AAA* a=b;
	
	// aaa 클래스의 포인터로 객체 b를 가리키면
	// 가려졌던 aaa 클래스의 fct 함수가 보이게 되어
	// aaa 클래스의 포인터로 fct 함수를 호출하면
	// aaa 클래스의 fct 함수가 호출되어야하지만
	// aaa 클래스의 fct 함수가 가상함수이므로
	// aaa 클래스의 fct 함수를 오버라이딩 하고있는
	// bbb 클래스의 fct 함수가 대신 호출된다.
	// 이 특성을 재정의 라고 한다.
	// 오버라이딩에서 버추얼 키워드를 사용하지 않으면
	// 은닉의 특성을 지니게 되고 
	// 버추얼 키워드를 사용하면 재정의의 특성을 지니게 된다.
	//
	a->fct();

	delete b;
	return 0;
}

//
// 멤버 함수를 가상(virtual)으로 선언하기
// : virtual 특성도 상속된다.
//
//