STL RTTI
6448 단어 RTTI
typeid의 역할은 프로그램이 실행될 때 되돌아오는 대상의 유형으로 사용하기에 일반 함수와 매우 비슷하며 되돌아오는 값은const typeinfo.sizeof와 유사하며 typeid는 유형이나 변수를 받아들일 수 있습니다.
type_info는 < type info > 에서 정의되며, typeid 연산자가 사용되기 전에 이 헤더 파일을 포함해야 합니다.
type 제외info,
// dynamic_cast , bad_cast
class bad_cast : public exception
{
public:
bad_cast() throw() { }
virtual ~bad_cast() throw();
virtual const char* what() const throw();
};
// typeid ,
class bad_typeid : public exception
{
public:
bad_typeid () throw() { }
virtual ~bad_typeid() throw();
virtual const char* what() const throw();
};
type_info의 공공 구성원은 다음과 같습니다.
virtual ~type_info();
/** , , type_info name() , */
const char* name() const;
/** before , , , , ? */
bool before(const type_info& arg) const;
bool operator==(const type_info& arg) const;
bool operator!=(const type_info& arg) const
네, 기본 구조 함수, 복사 구조 함수, 부수 연산자는private 또는protected입니다.이렇게 하면 당신은 type 을 세울 수 없습니다info 유형의 대상, typeid 연산자만 typeinfo 객체
typeid는 주로 다태적으로 하나의 기본 포인터를 판단하거나 파생 포인터를 가리키는지 인용하는 데 사용됩니다.
다음은 4개의 강제 유형 변환 조작부호 c++에 4개의 강제 유형 변환 조작부호가 있는데, 각각staticcast, dynamic_cast,const_cast,reinterpret_cast. 그것들은 사용하기에 템플릿 함수 같다.
1. reinterpretcast reinterpret_cast
2. constcast const_cast
3. staticcast가 실행되지 않을 때 형식 검사를 통해 전환의 안전성을 확보합니다. 사용법은 다음과 같습니다. ① 클래스 차원 구조에서 기본 클래스와 파생 클래스 사이의 지침이나 인용 변환에 사용됩니다.상행 변환(파생류의 지침이나 인용을 기류 표시로 변환)을 하는 것은 안전하다.하행 변환(기본 포인터나 인용을 파생 클래스 표시로 변환)을 할 때 동적 유형 검사가 없기 때문에 안전하지 않습니다.② int를char로 변환하고 int를enum으로 변환하는 등 기본 데이터 형식 간의 변환에 사용한다.이런 전환의 안전성도 개발자가 보증해야 한다.③ 빈 포인터를 대상 유형의 포인터로 변환합니다.④ 모든 형식의 표현식을void 형식으로 변환합니다.
4.dynamiccast dynamic_cast는 RTTI의 일부분으로 실행할 때 유형 변환을 하고 세 번째는 컴파일할 때 변환을 합니다.이 변환부호는 파생류를 가리키는 기본 포인터나 인용을 파생류를 가리키는 포인터나 인용으로 변환하는 데 사용됩니다.주의 dynamiccast 변환자는 허함수가 있는 클래스에만 사용할 수 있고 바늘이나 인용에만 사용할 수 있습니다.변환에 실패하면 포인터가 0값으로 되돌아오고 인용으로 바뀌면bad캐스트 이상입니다.
일부 경우 우리는 파생 클래스를 가리키는 기본 클래스 포인터 B가 파생 클래스 D의 허함수를 제외한 구성원을 방문하려면 이 포인터를 파생 클래스 D를 가리키는 포인터로 바꾸어 파생 클래스 D의 특유한 구성원을 방문하는 목적을 달성해야 한다. 예를 들어 파생 클래스 D에 특유한 구성원 함수 g()가 함유되어 있는 것보다 이 때 이 구성원을 방문할 수 있다.
dynamic_cast<D*>(pb)->g();
왜냐하면dynamiccast 전환 후의 결과는 파생류를 가리키는 지침이기 때문에 파생류 중의 특유의 구성원을 이렇게 방문할 수 있다.그러나 이 문장은 원래의 지침의 유형에 영향을 주지 않는다. 즉, 기류 지침 pb는 여전히 기류 B를 가리킨다.
또한dynamiccast는 다음 코드와 같이 크로스 변환(cross cast)도 지원합니다.
class A {
public:
int m_iNum;
virtual void f(){}
};
class B:public A {};
class D:public A {};
void foo() {
B *pb = new B;
pb->m_iNum = 100;
D *pd1 = static_cast<D*>(pb); // compile error
D *pd2 = dynamic_cast<D*>(pb); // pd2 is NULL
delete pb;
}
그런데 이게 무슨 소용이야?언젠가는 전환에 실패할 뿐만 아니라, 이 전환도 의미가 없다.대략dynamiccast는 허함수표를 통해 이루어진 부작용이죠!?
reinterpret_cast 및 static캐스트의 차이점:
class A
{
public:
int m_a;
};
class B
{
public:
int m_b;
};
class C : public A, public B {};
int main()
{
C c;
printf("%p, %p, %p", &c, reinterpret_cast<B*>(&c), static_cast<B*>(&c));
return 0;
}
출력: 0028FF18, 0028FF18, 0028FF1C
reinterpret_cast는 주소에 대한 강제 변환일 뿐입니다.static캐스트는 안전한 전환입니다.