2013. 12. 5. 22:10 C언어

c++ 공부 요점정리 25






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
// ##########################################
//
// 42 Virtual의 특성도 상속된다
//
// ##########################################
// 멤버 함수를 가상(virtual)으로 선언하기
// : virtual 특성도 상속된다.
//
//
//
#include <iostream>
using std::endl;
using std::cout;

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

class BBB : public AAA
{
public:
	// aaa 클래스의 가상함수 fct함수가 
	// bbb 클래스의 fct 함수에 의해서
	// 오버라이딩 되고 있다.
	// bbb 클래스가 상속하고있는 
	// aaa 클래스의 가상 fct 함수를
	// 오버라이딩을 하는 경우
	// 오버라이딩하는 bbb 클래스의 fct 함수도 자동으로
	// 가상함수로 선언되게 된다.
	// 따라서 명시적으로 가상을 선언하거나
	// 선언하지 않아도 같다.
	// 그러나 가독성을 위해서 가상을 선언해주는것이 좋다.
	// 
	void fct(){    // virtual void fct()
		cout<<"BBB"<<endl;
	}
};

class CCC : public BBB
{
public:
	// 마찬가지로 다음의 fct 함수도 가상함수가 된다.
	// ccc 클래스의 fct 함수는 가상함수가 되지만
	// 가상함수는 상속관계에 의해서 오버라이딩 되어
	// 질때만 의미를 가지기 때문에
	// 의미가 없는 가상함수가 된다.	
	void fct(){
		cout<<"CCC"<<endl;
	}
};


int main(void)
{
	// ccc 클래스의 객체를 생성하는데
	// bbb 클래스의 포인터로 ccc 클래스 객체를 가리킨다.
	// bbb 클래스의 포인터로 fct함수를 호출하니까
	// bbb 클래스의 fct를 호출하려고 보니
	// 가상함수이므로 이 함수를 오버라이딩하는 
	// 함수가 대신 호출되어 
	// ccc 클래스의 fct 함수가 호출된다.
	
	BBB* b=new CCC;
	b->fct();

	// aaa 클래스의 포인터도 ccc 클래스의 객체를 가리킨다.
	// aaa 클래스의 포인터로 fct 함수를 호출하니까
	// aaa 클래스의 fct 함수를 호출하는데
	// 가상함수이므로 aaa 클래스의 가상 fct 함수를 
	// 오버라이딩하고 있는 bbb 클래스의 가상 fct 함수를
	// 호출하고 
	// bbb 클래스의 fct 함수도 가상이므로
	// bbb 클래스의 fct 함수를 오버라이딩 하고있는
	// ccc 클래스의 fct 함수를 호출한다.
	
	AAA* a=b;
	a->fct();

	delete b;
	return 0;
}
//
// 만약 위의 예제에서 bbb 클래스도 없고, 
// ccc 클래스도 없다면 
// aaa 클래스의 가상함수 선언은 의미가 없다.
// aaa 클래스의 가상함수 fct를 호출하면 
// 그냥 호출된다.
// 따라서 가상함수는 가상함수고 속하는 클래스가 
// 상속되고, 
// 상속하는 클래스의 멤버 함수에 의해서
// 오버라이딩 되는 경우에 의미를 가진다.


//
// static binding vs dynamic binding
//
// 다음과 같이 선언 후 fct 함수를 호출하면
AAA* a = new ???
a->fct();
// 어디에 존재하는 fct 함수가 호출 될까?
// ???에 따라서 호출되는 fct 함수가 달라진다.
// 즉, 포인터에 따라서 호출되는 함수가 결정되는
// 것이 아니라
// 그 포인터가 가리키는 객체에 따라서 
// 호출되는 함수가 결정되는것이다.
// 이것을 다이나믹 바인딩이라 한다.
// 
// 다음과 같이 선언하면
AAA a;
a.fct();
// 항상 aaa 클래스의 fct 함수만 호출된다.
// 이것을 스태틱 바인딩이라 한다.

//
// 오버라이딩 된 함수의 호출이 필요한 이유
//
#include <iostream>
using std::endl;
using std::cout;

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

class BBB : public AAA
{
public:
	void fct(){
		// 오버라이딩된 aaa 클래스의 fct 함수를
		// 호출하는 방법 1
		AAA::fct();  
		cout<<"BBB"<<endl;
	}
};


int main(void)
{
	AAA* a=new BBB;
	cout<<"첫 번째 시도"<<endl;
	a->fct();  

	cout<<"두 번째 시도"<<endl;
	// 방법 2
	// 다음과 같이 범위를 지정해 주면
	// aaa 클래스의 fct 함수를 호출할 수 있다.
	// 이런 방법은 권장되지 않음
	// 첫번째 방법 사용 권장
	a->AAA::fct(); 

	return 0;
}

//
// 순수(pure) 가상함수와 추상 클래스
// 
// 추상 클래스는 하나이상의 순수 가상함수를
// 지니는 클래스로
// 추상 클래스는 완전한 클래스가 아니므로
// 객체화 될 수 없다.
// 객체화는 불가능하지만 포인터 선언까지 
// 불가능한것은 아니다.
//
class AAA
{
	private :
		int a;
	public :
		// 함수를 선언만 하지 정의를 하지 않는다
		virtual int fct()=0; // 순수 가상 함수
}









'C언어' 카테고리의 다른 글

c++ 공부 요점정리 27 멤버 함수의 위치  (0) 2013.12.09
c++ 공부 요점정리 26  (0) 2013.12.05
c++ 공부 요점정리 24  (0) 2013.12.04
c++ 공부 요점정리 23  (0) 2013.12.04
c++ 공부 요점정리 22  (0) 2013.12.04
Posted by 뮹실이

최근에 달린 댓글

05-18 12:46
Yesterday
Today
Total