파생 클래스에서 기초 클래스의 메서드를 다르게 사용해야 될 때가 있다. 호출하는 객체에 따라 메서드의 행동이 달라질 수도 있는데 이 때 다형상속이 필요하다.
다형 상속의 방법
- 기초 클래스 메서드를 파생 클래스에서 다시 정의한다.
- 가상 메서드를 사용한다.
class Test
{
...
virtual void Print() const;
};
class Test2
{
...
virtual void Print() const;
};
Test x(123, "sss");
Test2 y(13, "ss");
Test & t1 = x;
Test & t2 = y;
t1.Print(); //Test::Print()를 사용한다.
t2.Print(); //Test2::Print()를 사용한다.
- virtual 키워드를 사용하면 원래는 참조나 포인터를 사용하여 객체를 지시했을 경우 기초 클래스의 메서드를 선택하지만 가상 메서드는 지시한 객체에 따라 선택이 된다.
- 파생 클래스에서 정의되지 않은 기초 클래스의 메서드는 사용 범위 결정 연산자를 파생 클래스의 메서드에서 사용하지 않아도 된다.
- 메서드를 사용할 때 포인터나 참조를 사용하지 않았다면 자기 자신의 클래스의 메서드를 사용한다.
가상 파괴자
- 파괴자가 가상이 아니라면 포인터형에 해당하는 파괴자만 호출될 것이다.
- 파괴자가 가상이면 객체형에 해당하는 파괴자가 호출된다.
- 파생 클래스의 파괴자가 먼저 파괴 후에 기초 클래스를 자동으로 파괴한다.
- 파생 클래스에서 어떤 일을 하는 파괴자를 가지게 된다면 기초 클래스에 파괴자가 가상으로 제공하는 것이 좋다.
Test * xx = new Test2; //Test 기초클래스, Test2파생 클래스일 때
delete xx;
- Test가 기초 클래스고 가상소멸자를 가졌을 때는 xx는 Test2를 파괴하고 Test를 파괴한다.
- Test가 기초 클래스고 일반소멸자라면 Test만 파괴한다.
업캐스팅과 다운캐스팅
업캐스팅
파생 클래스의 참조나 포인터를 기초 클래스의 참조나 포인터로 변환하는 것을 업캐스팅이라 한다.
void fr(Brass & rb);
void fp(Brass * pb);
void fv(Brass b);
int main()
{
Brass b("dd", 123);
BrassPlus bp("dd", 123);
fr(b); //Brass
fr(bp); //BrassPlus
fp(b); //Brass
fp(bp); //BrassPlus
fv(b); //Brass
fv(bp); //Brass
}
- 위 함수를 통해 가상메서드를 사용할 경우 참조나 포인터를 사용하면 파생 클래스의 메서드를 사용한다. (암시적 업캐스팅)
- 값을 전달하면 파생 클래스를 넣어도 기초 클래스를 사용한다.
다운캐스팅
기초 클래스 포인터나 참조를 파생 클래스 포인터나 참조로 변환 하는 것을 다운캐스팅이라 한다.
다운 캐스팅은 명시적인 데이터형 변환 없이는 허용되지 않는다.
기초 클래스에 있는 메서드를 파생 클래스에서 다시 정의할 예정이라면, 그것을 가상함수로 선언해야 한다.
파생 클래스에서 다시 정의할 예정이 아니라면, 그것을 가상이 아닌 함수로 선언해야한다.
'C++ > Basic' 카테고리의 다른 글
[C++] 템플릿 클래스 (0) | 2021.07.19 |
---|---|
[C++] 다중 상속과 가상 기초 클래스 (0) | 2021.07.14 |
[C++] 클래스의 상속 (0) | 2021.07.05 |
[C++] 멤버 초기자 리스트 (0) | 2021.07.04 |
[C++] 대입 생성자 (0) | 2021.06.30 |