일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 캡슐화
- 동영상 강의
- C++
- 안드로이드 앱 개발
- 실습
- 표준 입출력
- 알고리즘
- c언어
- 파이썬
- Windows Forms
- 충남 천안
- 졸업 작품
- 프로젝트
- 졸업 작품 소재
- 소스 코드
- 언제나휴일
- c#
- 강의
- 소켓 통신
- 클래스 다이어그램
- 표준 라이브러리 함수
- 동영상
- 네트워크 프로그래밍
- 무료 동영상 강의
- 산책하기 좋은 곳
- 원격 제어 프로그램
- 언제나 휴일
- 유튜브 동영상 강의
- 실습으로 다지는 c#
- 추천
Archives
- Today
- Total
프로그래밍 언어 및 기술 [언제나휴일]
[C++] 37. 하향 캐스팅 본문
이번에는 기반 형식 포인터 변수로 참조하고 있는 형식을 프로그램 동작 시에 파생 형식으로 형 변환하는 하향 캐스팅을 알아보기로 해요.
다형성은 캡슐화와 상속을 보다 효과적이고 현실 세계에 근접하게 표현할 수 있게 해주는 특징입니다. 하지만 기반 클래스 형식 포인터 변수로 파생 개체를 관리하는 것은 치명적인 단점이 있습니다.
만약 기반 클래스 형식에서는 약속할 필요가 없는 메서드가 파생 클래스 형식에 있을 때 해당 메서드의 접근 수준을 public으로 제공해도 접근하지 못합니다. 이러한 약점을 보완하기 위해 많은 OOP언어에서는 런 타임에 파생 개체 형식으로 형 변환(캐스팅)하는 방법을 제공하고 있으며 이를 하향 캐스팅이라 합니다.
C++언어에서는 dynamic_cast를 통해 하향 캐스팅을 제공하고 있습니다. dynamic_cast를 사용하면 원하는 형식으로 캐스팅이 가능한지 확인할 수 있습니다. 만약 캐스팅할 수 없다면 0을 반환하고 캐스팅할 수 있다면 유효한 변환을 해 줍니다.
Pianist *pianist=0;
pianist = dynamic_cast<Pianist *>(musician);//musician이 피아니스트인지 하향 캐스팅
if(pianist)//피아니스트가 맞다면
{
pianist->Tuning();
}
다음은 음악가에서 파생받은 피아니스트와 드러머를 정의하고 하향 캐스팅을 통해 피아니스트 클래스에만 있는 조율 기능을 사용하는 예제 코드입니다.
//하향 캐스팅
//Program.cpp
#include <iostream>
#include <string>
using namespace std;
class Musician
{
string name;
public:
Musician(string name)
{
this->name = name;
}
string GetName()const
{
return name;
}
virtual void Play()=0;
};
class Pianist:public Musician
{
public:
Pianist(string name):Musician(name)
{
}
virtual void Play()
{
cout<<GetName()<<" 딩동댕 ♩♪♬"<<endl;
}
void Tuning()
{
cout<<"도도 레레 미미 파파"<<endl;
}
};
class Drummer:public Musician
{
public:
Drummer(string name):Musician(name)
{
}
virtual void Play()
{
cout<<GetName()<<" 두두둥~~~"<<endl;
}
};
int main()
{
Musician *musicians[2];
musicians[0] = new Pianist("피아노맨");
musicians[1] = new Drummer("두둥맨");
Pianist *pianist=0;
for(int i = 0; i<2; i++)
{
pianist = dynamic_cast<Pianist *>(musicians[i]);//players[i]가 피아니스트인지 하향 캐스팅
if(pianist)//피아니스트가 맞다면
{
pianist->Tuning();
}
musicians[i]->Play();
}
for(int i=0;i<2;i++)
{
delete musicians[i];
}
return 0;
}
▷ 실행 결과
도도 레레 미미 파파
피아노맨 딩동댕 ♩♪♬
두둥맨 두두둥~~~
하지만 일반화 관계일 때 언제나 dynamic_cast를 지원하지는 않습니다. 만약 가상 메서드를 정의한 것이 없으면 dynamic_cast를 지원하지 않아요. 따라서 dynamic_cast를 사용하려면 가상 메서드가 하나 이상 정의한 형식이어야 합니다.
//하향 캐스팅 오류
//Program.cpp
#include <iostream>
#include <string>
using namespace std;
class Musician
{
string name;
public:
Musician(string name)
{
this->name = name;
}
string GetName()const
{
return name;
}
void Play()
{
cout<<name<<" 연주하다."<<endl;
}
};
class Pianist:public Musician
{
public:
Pianist(string name):Musician(name){ }
void Tuning()
{
cout<<"도도 레레 미미 파파"<<endl;
}
};
class Drummer:public Musician
{
public:
Drummer(string name):Musician(name){ }
};
int main()
{
Musician *musicians[2];
musicians[0] = new Pianist("피아노맨");
musicians[1] = new Drummer("두둥맨");
Pianist *pianist=0;
for(int i = 0; i<2; i++)
{
pianist = dynamic_cast<Pianist *>(musicians[i]);//가상 메서드가 없어서 컴파일 오류
if(pianist)//피아니스트가 맞다면
{
pianist->Tuning();
}
musicians[i]->Play();
}
for(int i=0;i<2;i++)
{
delete musicians[i];
}
return 0;
}
'C & C++ > 디딤돌 C++' 카테고리의 다른 글
[C++] 41. 상속과 다형성 최종 실습 시나리오 (0) | 2024.04.08 |
---|---|
[C++] 40. 상속과 다형성 실습2 (도형) (0) | 2024.04.08 |
[C++] 39. 상속, 다형성 실습1 (상품, 할인 상품) (0) | 2024.04.08 |
[C++] 38. C++에서의 형 변환 (0) | 2024.04.08 |
[C++] 36. 다중 상속 (0) | 2024.04.08 |
[C++] 35. 인터페이스 (INTERFACE) (0) | 2024.04.08 |
[C++] 34. 추상 클래스(ABSTRACT CLASS) (0) | 2024.04.08 |
[C++] 33. 메서드의 다형성 (0) | 2024.04.07 |