[c++] C ++에서 객체 유형 찾기

클래스 A와 클래스 B를 상속받는 다른 클래스가 있습니다 .A 유형의 객체를 매개 변수로 허용하는 함수를 재정의하고 있으므로 A를 수락해야합니다. 그러나 나중에 B 만있는 함수를 호출합니다. 따라서 전달 된 객체가 B 유형이 아닌 경우 false를 반환하고 진행하지 않고 싶습니다.

객체가 함수에 전달한 유형을 찾는 가장 좋은 방법은 무엇입니까?



답변

dynamic_cast가 트릭을 수행해야합니다

TYPE& dynamic_cast<TYPE&> (object);
TYPE* dynamic_cast<TYPE*> (object);

dynamic_cast키워드는 캐스트의 유효성을 보장하기 위해 런타임 검사를 수행, 다른 하나 개의 포인터 또는 참조 유형에서 데이텀을 캐스팅합니다.

실제 객체 유형이 아닌 유형에 대한 포인터를 캐스트하려고하면 캐스트 결과는 NULL입니다. 실제 객체 유형이 아닌 유형을 참조하기 위해 캐스트하려고하면 캐스트에서 bad_cast예외 가 발생합니다.

dynamic_cast가 작동하도록 Base 클래스에 하나 이상의 가상 함수가 있는지 확인하십시오.

위키 백과 주제 런타임 유형 정보

RTTI는 다형성 클래스에만 사용할 수 있습니다. 즉, 하나 이상의 가상 메소드가 있습니다. 실제로, 기본 클래스에는 파생 클래스의 객체가 기본 포인터에서 삭제 된 경우 적절한 정리를 수행 할 수 있도록 가상 소멸자가 있어야하므로 제한이 없습니다.


답변

동적 캐스트는 문제 설명에 가장 적합하지만 다음과 같이 클래스 유형을 찾을 수 있다고 덧붙이고 싶습니다.

#include <typeinfo>

...
string s = typeid(YourClass).name()


답변

이것을 RTTI 라고 부르지 만, 타입을 찾아서 그것을 기반으로 특별한 작업을 수행하면 코드가 더 부서지기 쉽기 때문에 디자인을 다시 생각하고 싶을 것입니다.


답변

완료하기 위해 Robocide에서 빌드를 빌드하고 typeidname ()을 사용하지 않고 단독으로 사용할 수 있음을 지적합니다 .

#include <typeinfo>
#include <iostream>

using namespace std;

class A {
public:
    virtual ~A() = default; // We're not polymorphic unless we
                            // have a virtual function.
};
class B : public A { } ;
class C : public A { } ;

int
main(int argc, char* argv[])
{
    B b;
    A& a = b;

    cout << "a is B: " << boolalpha << (typeid(a) == typeid(B)) << endl;
    cout << "a is C: " << boolalpha << (typeid(a) == typeid(C)) << endl;
    cout << "b is B: " << boolalpha << (typeid(b) == typeid(B)) << endl;
    cout << "b is A: " << boolalpha << (typeid(b) == typeid(A)) << endl;
    cout << "b is C: " << boolalpha << (typeid(b) == typeid(C)) << endl;
}

산출:

a is B: true
a is C: false
b is B: true
b is A: false
b is C: false


답변

아마도 개체에 ID “태그”를 포함시키고 클래스 A의 개체와 클래스 B의 개체를 구별하는 데 사용합니다.

그러나 이것은 디자인의 결함을 보여줍니다. 이상적으로 A에없는 B의 메소드는 A의 일부이지만 비워 두어야하고 B가이를 덮어 씁니다. 이것은 클래스 별 코드를 없애고 OOP의 정신에 더 가깝습니다.


답변

당신이 찾고있는 dynamic_cast<B*>(pointer)


답변

당신의 클래스는 다형성이 아니기 때문입니다. 시험:

struct BaseClas { int base; virtual ~BaseClas(){} };
class Derived1 : public BaseClas { int derived1; };

이제 BaseClas다형성입니다. 구조체의 멤버는 기본적으로 공개이기 때문에 클래스를 구조체로 변경했습니다.