2009-12-31 1 views
102

차이점은 무엇입니까 typeidtypeof C++에서 궁금합니다. 여기에 내가 무엇을 알고 :'typeid'대 'typeof'는 C++에서

  • typeid은 C++ 헤더 파일 typeinfo에 정의되어 type_info에 대한 설명서에 언급되어있다.

  • typeof은 C의 GCC 확장과 C++ Boost 라이브러리에서 정의됩니다.

또한, 여기에 내가 typeid 내가 무엇을 기대 반환하지 않는 것을 발견했습니다 어디 만든 테스트 코드 테스트입니다. 왜?

MAIN.CPP

#include <iostream> 
#include <typeinfo> //for 'typeid' to work 

class Person { 
    public: 
    // ... Person members ... 
    virtual ~Person() {} 
}; 

class Employee : public Person { 
    // ... Employee members ... 
}; 

int main() { 
    Person person; 
    Employee employee; 
    Person *ptr = &employee; 
    int t = 3; 

    std::cout << typeid(t).name() << std::endl; 
    std::cout << typeid(person).name() << std::endl; // Person (statically known at compile-time) 
    std::cout << typeid(employee).name() << std::endl; // Employee (statically known at compile-time) 
    std::cout << typeid(ptr).name() << std::endl;  // Person * (statically known at compile-time) 
    std::cout << typeid(*ptr).name() << std::endl;  // Employee (looked up dynamically at run-time 
                 // because it is the dereference of a pointer 
                 // to a polymorphic class) 
} 

출력 :

bash-3.2$ g++ -Wall main.cpp -o main 
bash-3.2$ ./main 
i 
6Person 
8Employee 
P6Person 
8Employee 
+6

당신이 당신의 코드가 올바른 유형 이름을 인쇄하지 않습니다 생각하십니까? 그것은 나에게 좋아 보인다. 'name()'에 의해 반환 된 실제 문자열은 구현에 따라 정의됩니다. 유효한 C++ 식별자 이름 일 필요는 없습니다. 유형을 고유하게 식별하는 * something * 일뿐입니다. 당신의 구현이 컴파일러의 일반적인 이름 - mangling scheme을 사용하는 것처럼 보입니다. –

+0

감사합니다. Rob! 나는 en.wikipedia.org/wiki/Typeid에서 본 것과 똑같은 타입의 이름을 기대하고있었습니다. 여기서 이름 짓기는 무엇입니까? – Tim

답변

139

C++ 언어 typeof 같은 것은이 없습니다 예를 들어, catanimal을 유도 말할 수 있습니다. 일부 컴파일러 관련 확장 프로그램을보아야합니다. GCC의 typeof에 대해 이야기하고 있다면, 비슷한 기능이 C++ 11에 키워드 decltype을 통해 존재합니다. 다시 C++에는 typeof 키워드가 없습니다.

typeid은 런타임에 형식 식별 정보를 반환하는 C++ 언어 연산자입니다. 기본적으로 type_info 개체를 반환하며 이는 다른 type_info 개체와 동일한 수준입니다.

주, 반환 type_info 객체 만 정의 속성을 가지고 그것 equality- 비 평등 비교되고, type_info 객체가 같은 형태를 기술하면서, 동일하지 않은 비교한다 다른 타입을 설명하는 예 type_info 오브젝트를 가지고 평등을 비교하라. 다른 모든 것은 구현에 따라 정의됩니다. 다양한 "이름"을 반환하는 메서드는 사람이 읽을 수있는 것을 반환하지 않으며 전혀 반환하지 않을 수도 있습니다.

typeid의 동일한 유형에 대한 연속 응용 프로그램이 다른 type_info 개체를 반환 할 수도 있음을 의미합니다 (물론 표준은 명시 적으로 언급하지는 않지만).).

+0

감사합니다, AndreyT! 방금 몇 가지 새로운 질문으로 게시물을 업데이트했습니다. 가능한 한 살펴보십시오. – Tim

+0

C++ 11에'decltype'이 있기 때문에 업데이트가 필요하지 않습니까? 나는 일반적인 정책이 무엇인지 모르겠다. 그러나 질문에'C++ '라는 태그가 붙어있어서 최신 표준을 참고하기를 기대한다. 'C++ 03'로 질문을 다시 붙이면 옵션이 될 수도 있습니다. 저는 직장에서 preC++ 11을 사용해야하고 때로는 사실 "pre11"또는 "post11"이 무엇인지 확실하지 않기 때문에 개인적으로 때때로 혼란스러워집니다. – user463035818

+0

FYI,'decltype'은'typeof'를 대체하지 않습니다. 'typeof'는'decltype'은 타입에 대해서도 작동합니다. 예를 들어,'typeof (int)'는'int'이고'decltype (int)'는 에러입니다. – Shahbaz

34

두개의 주된 차이점은 다음과 같다

  • 대해서 typeof 인 컴파일 시간 구조체 반환 에 정의 된 형식 컴파일 시간
  • typeid는 런타임 구조이므로 값의 런타임 유형에 대한 정보를 제공합니다.

대해서 typeof Refenence : http://www.delorie.com/gnu/docs/gcc/gcc_36.html

유형 ID를 Rfeerence : http://en.wikipedia.org/wiki/Typeid

+0

감사합니다. JaredPar! 답장을 읽은 후 업데이트 된 게시물에 몇 가지 새로운 질문이 있습니다. 반환 값이 다른 용도로 사용되는 경우도 마찬가지입니다. typeof를 반환하면 변수를 정의 할 수있는 type 키워드로 사용되지만 typeid를 반환 할 수 없습니까? – Tim

23

typeid 런타임에서 동작, 그리고 오브젝트 포인터이어야 오브젝트의 런타임 유형을 설명하는 객체를 반환 할 RTTI (run-time type information)이 클래스에 저장되도록 가상 메서드가있는 클래스. 또한 런타임 유형 정보가있는 클래스에 대한 포인터가 지정되지 않은 경우 컴파일 시간 유형의 표현식이나 유형 이름을 제공 할 수 있습니다.

typeof은 GNU 확장이며 컴파일 타임에 모든 표현식의 유형을 제공합니다. 예를 들어, 여러 유형에서 사용될 수있는 매크로에서 임시 변수를 선언 할 때 유용 할 수 있습니다. C++에서는 보통 templates을 대신 사용합니다.

+4

필자가 아는 한,'typeid'는 가상 메소드를 가진 객체로 평가하는 표현식뿐만 아니라 어떤 표현식이라도 받아 들일 것입니다. 게다가,'typeid'는 단지 표현식뿐만 아니라 * name * 타입을 받아 들일 것입니다. 원하는 경우'typeid (5)'또는'typeid (std :: string)'이라고 말할 수 있습니다. –

+1

나는 분명히하기 위해 나의 대답을 분명히했다; 'typeid' *는 가능하다면 런타임 타입 정보를 반환 할 수 있지만, 다른 어떤 것에 대해서는 컴파일 타임 타입 정보를 제공 할 수 있습니다. –

+0

감사합니다, Brian and Rob!답장을 읽은 후 업데이트 된 게시물에 몇 가지 새로운 질문이 있습니다. – Tim

19

추가 질문에 대답 : 유형 ID에 대한

내 다음 테스트 코드 출력하지 올바른 유형의 이름을 수행합니다. 무엇이 잘못 되었나요?

아무런 문제가 없습니다. 당신이 보는 것은 타입 이름의 문자열 표현입니다. 표준 C++은 컴파일러가 클래스의 정확한 이름을 출력하도록 강요하지 않으며, 무엇이 적합한 지 결정하는 것은 구현 자 (컴파일러 공급 업체)에게 달려 있습니다. 즉, 이름은 컴파일러에 달려 있습니다.


이들은 두 가지 도구입니다.typeof은 표현식의 유형을 반환하지만 표준이 아닙니다. C++ 0x에는 AFAIK라는 동일한 작업을 수행하는 decltype이라는 것이 있습니다.

decltype(0xdeedbeef) number = 0; // number is of type int! 
decltype(someArray[0]) element = someArray[0]; 

반면에 typeid은 다형성 유형과 함께 사용됩니다.

animal* a = new cat; // animal has to have at least one virtual function 
... 
if(typeid(*a) == typeid(cat)) 
{ 
    // the object is of type cat! but the pointer is base pointer. 
} 
+0

고맙습니다, 아락! 방금 몇 가지 새로운 질문으로 게시물을 업데이트했습니다. 가능한 한 살펴보십시오. – Tim

2
당신은 좋은 찾고 이름을 달성하기 위해 부스트 디맹 글링을 사용할 수 있습니다

:에 대해 물었을 때,

To_main_msg_evt ev("Failed to initialize cards in " + boost::units::detail::demangle(typeid(*_IO_card.get()).name()) + ".\n", true, this); 
4

유형 ID는 런타임시 데이터의 유형을 제공 같은

#include <boost/units/detail/utility.hpp> 

뭔가를. Typedef는 그 이후에 설명 된대로 새로운 유형을 정의하는 컴파일 타임 구문입니다. 출력과 같이 나타납니다 ++ C에서 더 대해서 typeof은 (새겨 주석으로 표시)이 없다 : 어떤 방법으로

std::cout << typeid(t).name() << std::endl; // i 
std::cout << typeid(person).name() << std::endl; // 6Person 
std::cout << typeid(employee).name() << std::endl; // 8Employee 
std::cout << typeid(ptr).name() << std::endl;  // P6Person 
std::cout << typeid(*ptr).name() << std::endl;  //8Employee