C++에서 객체의 실제 유형이 동일한 클래스가 아닌 동일한 클래스 또는 파생 클래스가 아닌지 알고 싶습니다. 이것은 다음 C# 코드와 유사합니다.C++에서 유형 검사
Class Base
{
}
Class Child:Base
{
}
Base childObject = new Child();
If (childObject.GetType() == typeof(Child))
{
// do some code
}
고마워요!
C++에서 객체의 실제 유형이 동일한 클래스가 아닌 동일한 클래스 또는 파생 클래스가 아닌지 알고 싶습니다. 이것은 다음 C# 코드와 유사합니다.C++에서 유형 검사
Class Base
{
}
Class Child:Base
{
}
Base childObject = new Child();
If (childObject.GetType() == typeof(Child))
{
// do some code
}
고마워요!
두 가지 방법으로이 작업을 수행 할 수 있습니다. 먼저 typeid
연산자를 사용할 수 있습니다.이 연산자는 객체 유형에 대한 정보가 들어있는 type_info
구조체를 반환합니다. 당신이 typeid(*ptr)
를 사용할 필요가 여기에 있지 typeid(ptr)
Base* ptr = /* ... */
if (typeid(*ptr) == typeid(DerivedType)) {
/* ... ptr points to a DerivedType ... */
}
공지 예를 들면 다음과 같습니다. typeid(ptr)
을 사용하는 경우 Base*
에 대한 포인터는 Base*
이므로 포인터는 Base*
인 type_info
개체를 반환합니다.
주목할 점은 ptr
이 정확히 이고이 DerivedType
으로 표시되는지 확인하는 것입니다. ptr
이 DerivedType
(아마도 EvenMoreDerivedType
)에서 파생 된 유형의 객체를 가리키는 경우이 코드는 올바르게 작동하지 않습니다.
좀 더 견고한 유형의 개체를 가리키는 지 확인하는 다른 방법은 dynamic_cast
연산자를 사용하는 것입니다. dynamic_cast
은 런타임시 검사 된 유형 변환을 수행하여 유형 변환이 성공하면 유효한 포인터를 생성하고 그렇지 않으면 NULL을 리턴합니다. 예를 들면 :
EvenMoreDerivedType
같은에서
ptr
경우 점, 캐스트는 여전히
EvenMoreDerivedType
상속 때문에
DerivedType
에서 성공하는 추가 장점이있다
Base* ptr = /* ... */;
DerivedType* derived = dynamic_cast<DerivedType*>(ptr);
if (derived) {
/* ... points to a DerivedType ... */
}
.
최종 생각으로, 당신은 종종 다음과 같은 코드를 참조하십시오
Base* ptr = /* ... */
if (DerivedType* derived = dynamic_cast<DerivedType*>(ptr)) {
/* ... points to a DerivedType ... */
}
이는 if
문의 본체에 derived
포인터를 로컬 스코프와 제로가 아닌 값이 C++로 true
로 평가한다는 사실을 사용합니다. 필자는 개인적으로 읽기 쉽고 오류가 발생하기 쉽지만, 가장 쉬운 방법은 사용자에게 쉽습니다.
희망이 도움이됩니다.
그는 파생 된 클래스가 아니라 객체가 Base인지 여부를 알고 싶어합니다. – Puppy
아 ... 포인터가 자식 형식을 가리키는 지 확인하는 예제 코드로 인해 혼란스러워합니다. 유효한 포인트. – templatetypedef
typeid()를 사용할 수 있습니다.
if (typeid(childObject) == typeid(ChildType)) {
}
이 값이 참이면 자식 클래스라는 것을 알게됩니다.
런타임 유형 식별 (RTTI)을 사용하여 컴파일해야합니다. –
비교되는 항목에 vtbl이있는 경우에만 **이 기능이 ** 작동합니다. –
@Billy : 사실입니다.하지만 누가 기본 클래스에 가상 소멸자를 제공하지 않습니까? 가상 함수는 사실상 상속의 포인트입니다. 그것을 기대하는 것은 무리가 아닙니다. – Puppy
DeadMG의 대답은 정확하지만 (나는 여러 번 typeid를 사용했습니다), 나는 이것을 후세에 던질 것이라고 생각했습니다. 객체 지향 뷰에서이를 수행하는 "올바른"방법은 다음과 같습니다.
Class Base
{
virtual void something() {
// probably a no-op, but maybe some default stuff
}
}
Class Child : public Base
{
virtual void something() {
// do your child-specific code here
}
}
Base* childObject = new Child();
childObject->something(); // does the right thing
나는이 대답을 초. DeadMG의 대답은 올바른 프로그래밍 연습이 아니지만 ...! –
이것은 개체 내부에 뭔가를하고 싶을 때 잘 작동합니다. 반면에 유형에 따라 객체를 처리하려는 경우 복잡하고 불편 해집니다 (모든 이중 디스패치 및 방문자의 경우) –
@ 7vies, true이지만 가장 일반적으로이 가상 메서드 접근 방식이 가장 효과적 일 수 있습니다. 유지 관리가 가장 쉽다. dynamic_cast 또는 typeid가 올바른 접근 방법 인 경우가 있지만 그보다 드문 경우입니다. – Tim
'childObject' 유형은 무엇입니까? 런타임시에 타입의 개념이 존재하지 않기 때문에 C++에서 이것을 수행하는 일반적인 방법은 없습니다. –
자, 질문을 편집하겠다. – Homam
childObject.GetType()이 무엇인지에 대해서는 언급하지 않았지만 그럼에도 불구하고이 코드는 타입 비교에서 분기하기 때문에 끔찍한 코드이다. 그것이 OOP가 제거해야하는 것입니다. –