순수 가상 함수에 대해 공부합시다.
순수 가상함수란?
- 함수의 정의는 없으며 오직 다형성 파생 클래스에 오버라이드(override)만으로 적용되는 함수입니다.
virtual void Open() = 0;
요런 형태가 됩니다.
이렇게 선언된 순수 가상 함수가 있는 클래스는 보통 추상 클래스(abstract class) 라고 부릅니다.
이러한 추상클래스에 특징은 절대로 자기 혼자 객체화를 시킬수가 없습니다.
왜 이러한 추상 클래스를 사용을 하는가에는
ex) 예를들어 자동차가 있으면 그 자동차에도 스포츠 자동차가 있고 일반차가 있으면 차에 문을 위로 올리는 차
아래로 올리는 차로 나눌수 있습니다.
또한 추상클래스를 상속받는 클래스들은 순수가상함수를 반드시 재정의를 해줘야하기때문에 강제성도 보장합니다.
이를 통해 자동차라는 추상 클래스를 만들어 스포츠 자동차 일반 자동차에 각각 상속을 시켜 여러가지 다양하게 만들수 있게 흔히 뼈대를 잡을수가 있습니다.
안되는 코드 예제
#include<iostream>
using namespace std;
class Car
{
public :
virtual void Open() = 0;
};
class BasicCar : public Car
{
public:
void Open()
{
cout << "옆으로 열림" << endl;
}
};
class SuperCar : public Car
{
public:
void Open()
{
cout << "위로 열림" << endl;
}
};
int main()
{
Car* c = new Car();
}
이러한 경우 컴파일러가 Car는 추상 클래스입니다. 객체 선언이 불가능합니다 라고 에러를 뿝게 됩니다.
그럼 어떻게 코드를 예쁘게 짜줘야 하나?
방법은 여러가지가 있지만 슈퍼카, 스포츠카를 직접 객체(인스턴스)화를 하여 부르는 방법도 있습니다.
BasicCar* b = new BasicCar();
b->Open();
SuperCar* s = new SuperCar();
s->Open();
또한 이러한 방법도 가능합니다.
Car* b = new BasicCar();
b->Open();
Car* s = new SuperCar();
s->Open();
이 방법 또한 추상 클래스 포인터가 BasicCar랑 SuperCar를 가르키며 동적 할당을 할 경우 입니다.
실직적인 virtual 함수는 런타임에 의해 v테이블 안에 각각 가르키고 있는 객체 즉 자식 클래스 오버라이드 된 함수에 주소를 가르키고 있는 가상 함수 포인터가 있기 때문입니다.
Override 키워드
C++ 에는 Override 라는 키워드가 있습니다.
void Open() override;
요렇게 사용하는 키워드입니다. 재정의(override) 하는 함수 뒤에 override 라는 키워드만 붙혀주면 됩니다.
이렇게 사용을 하는 이유는 사용자의 실수를 막기위함이 매우 큽니다.
override 키워드를 붙히면 컴파일러는 이 함수가 부모로부터 재정의(override)를 할려는 함수인지 검사를 하게 됩니다.
만약 이 함수가 override를 한 함수가 아니라면 즉 부모에 virtual 키워드가 붙지않고 함수 이름 매개변수 또한 매칭이 안되면 바로 오류를 뿜게 됩니다.
#include<iostream>
using namespace std;
class Car
{
public :
void Open()
{
}
};
class BasicCar : public Car
{
public:
void Open() override // 에러
{
cout << "옆으로 열림" << endl;
}
};
class SuperCar : public Car
{
public:
void Open() override // 에러
{
cout << "위로 열림" << endl;
}
};
int main()
{
Car* b = new BasicCar();
b->Open();
Car* s = new SuperCar();
s->Open();
}
이런식으로 말입니다.
'개발자 면접 공부 > C-C++' 카테고리의 다른 글
C++ 캐스팅의 종류 (0) | 2022.07.14 |
---|---|
C++ RTTI 에 대해 (0) | 2022.07.14 |
C++ Virtual(가상) 함수 (0) | 2022.07.12 |
C++ 포인터(Pointer) 레퍼런스(Reference) 차이 (0) | 2022.07.11 |
댕글링 포인터(Dangling Pointer) (0) | 2022.07.11 |