2009-04-25 4 views
17
class foo 
{ 
public: 
    void say_type_name() 
    { 
    std::cout << typeid(this).name() << std::endl; 
    } 
}; 

int main() 
{ 
    foo f;; 
    f.say_type_name(); 
} 

Над кодом отпечатков P3foo на моей машине Ubuntu с г ++. Я не понимаю, почему это печатает P3foo вместо foo. Если изменить код какTypeId() возвращает дополнительные символы в г ++

std::cout << typeid(*this).name() << std::endl; 

печатает 3foo.

Любые мысли?

ответ

31

Потому что это указатель на foo. И foo имеет 3 символа. Таким образом, он становится P3foo. Другой имеет тип foo, поэтому он становится 3foo. Обратите внимание, что текст зависит от реализации, и в этом случае GCC просто дает вам внутреннее, искаженное имя.

Введите это искаженное имя в программе c++filt получить unmangled имя:

$ c++filt -t P3foo 
foo* 
+0

WOW! Интересно. Еще два вопроса .. 1 - C++ filt является частью дистрибутива gcc или частью LINUX? 2 - Есть ли способ получить искаженное имя метода или класса? –

+0

C++ filt является частью binutils (пакет, в котором ld (компоновщик) и другие небольшие utils, такие как readelf, также поступают): http://www.gnu.org/software/binutils/ –

+5

нет способа сделайте это на C++. Однако в GCC существует функция, открытая ABI, которая делает это. Он находится в cxxabi.h и называется __cxa_demangle. просто передайте ему искаженное имя. Его интерфейс следует за этим ABI: http://www.codesourcery.com/public/cxx-abi/abi.html#demangler –

17

std::type_info::name() возвращает реализацию конкретного имени. AFAIK, нет никакого портативного способа получить «приятное» имя, хотя GCC has one. Посмотрите на abi::__cxa_demangle().

int status; 
char *realname = abi::__cxa_demangle(typeid(obj).name(), 0, 0, &status); 
std::cout << realname; 
free(realname); 
+0

Спасибо за это! Это была большая помощь в моем текущем проекте. –

0

Есть ли портативное решение

обходной путь будет сделать шаблон взломать, чтобы вернуть все harcoded имена типов, как char*

какая платформа не имеют #include <cxxabi.h>?

+1

Без специальной поддержки самого класса (например, 'whoami()') любой «шаблонный взлом» может выводить только * статический * тип, а не * динамический * один (рассмотрите указатель на полиморфный базовый класс). –

+0

Qt обеспечивает очень хороший механизм отражения с его системой метаобъектов. Я рекомендую его очень. –