순수가상함수?
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
|
class A {
public:
virtual void f(){
cout << "A::f()" << endl;
}
};
class B :public A {
public:
void f(){
cout << "B::f()" << endl;
}
};
int main() {
A* a = new A;
a->f();
delete a;
}
|
cs |
이런 상태에서 a의 가상함수인 f를 호출한다면 a에 있는 f함수가 호출된다.
근데 순수 가상함수는 아무것도 호출되지 않는 함수이다.
virtual void f()=0; 같은 애를 순수가상함수라고 한다.
이렇게 되면
인스턴스를 생성할수 없다.
그리고 그런 클래스를 추상클래스라고 한다.
대신 상속을 통해 오버라이딩하면 자식클래스는 객체를 만들수 있다.
++) 한번 가상함수로 선언된 함수는 따로 virtual 키워드를 앞에 써주지 않아도 가상함수로 인식합니다.
그렇다면 순수가상함수를 왜 쓰는 것일까?
가상함수의 허점은 부모 클래스에서 구현한 가상함수를 반드시 자식클래스가 구현해야한다는 강제성이 없다.이러면 클래스 상속을 통해서 오버라이딩을 안하게 되기에 다형성을 구성하지 못한다. 근데 순수가상함수를
쓰면 해당 클래스에서는 구현할 수 없고 상속받은 자식클래스에서 반드시 재정의 해야하기 때문에 다형성을 구성할 수 있다.
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
|
class Shape {
public:
virtual double GetArea() = 0;
virtual void Resize(double f) = 0;
};
class Circle :public Shape{
public:
Circle(double r):r(r){}
double GetArea() {
return 3.14 * r * r;
}
void Resize(double f) {
r *= f;
}
private:
double r;
};
class Rectangle:public Shape {
public:
Rectangle(double a,double b):a(a),b(b){}
double GetArea() {
return a * b;
}
void Resize(double f) {
a *= f;
b *= f;
}
private:
double a, b;
};
int main() {
//포인터 배열로 만들어줌
Shape *shapes[] = {
new Circle(10),
new Rectangle(20,30),
};
for (Shape* s : shapes) {
s->Resize(2);
}
for (Shape * s : shapes) {
cout << s->GetArea() << endl;
}
for (Shape* s : shapes) {
delete s;
}
}
|
cs |
위의 예시처럼 추상클래스는 부모클래스로 부터 무조건 받아와야 하는 함수가 있을 때 (Resize,GetArea같은)
그것을 강제하기에 유용한 역할을 한다.
그리고 클래스 포인터배열을 선언해줌으로써 주소값을 배열에 담는다.
그냥 배열에 담게 되면 그 클래스로 부터 상속받은 자식클래스의 멤버에는 접근 할 수 없다.
그리고 동적할당 했기 때문에 delete 해주는 것도 잊지 않아야한다.
++) 중요!
가상함수를 오버라이딩 했다면 앞에 virtual을 쓰지 않았더라도 virtual이 숨겨져 있는 것
가상함수에서는 실제로 가리키는게 중요하다.
예를 들어 A가 부모클래스이고, B가 자식클래스이며 두 클래스 모두 f라는 가상함수가 오버라이딩 되어있다고 해보자.
A *a=new B; 일때 a라는 포인터 변수가 실제로 가리키는게 B 클래스이기에
a->f()라면
B 클래스의 f함수를 호출한다. 실제 객체의 타입이 A더라도 가상함수에서는 실제로 가리키는 B를 바탕으로 작동한다.
'C++ > 기초(두들낙서)' 카테고리의 다른 글
[C++] 상속에서의 형변환 (💢static_cast다시보기) (0) | 2022.07.12 |
---|---|
[C++] 상속관계에서 생성/소멸자의 실행순서와 가상 소멸자 (0) | 2022.07.12 |
[C++] 오버라이딩과 정적바인딩 / 가상함수와 동적바인딩 (0) | 2022.07.10 |
Polygon 연습문제 (0) | 2022.07.10 |
[C++] 묵시적 형변환 (0) | 2022.07.10 |
댓글