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

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

Por encima de código imprime P3foo en mi máquina ubuntu con g ++. No entiendo por qué está imprimiendo P3foo en lugar de solo foo. Si cambio el código comotypeid() devuelve caracteres adicionales en g ++

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

imprime 3foo.

¿Alguna idea?

Respuesta

31

Porque es un puntero a foo. Y foo tiene 3 personajes. Entonces se convierte en P3foo. El otro tiene el tipo foo, por lo que se convierte en 3foo. Tenga en cuenta que el texto depende de la implementación, y en este caso, GCC simplemente le da el nombre interno y mutilado.

entrar en ese nombre revuelto en el programa c++filt para obtener el nombre unmangled:

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

¡WOW! Interesante. Dos preguntas más ... 1 - C++ filt es parte de la distribución de gcc o parte de LINUX? 2 - ¿Hay alguna forma de obtener el nombre destrozado de un método o clase? –

+0

C++ filt es parte de binutils (el paquete donde también vienen ld (el enlazador) y las otras utilidades pequeñas como readelf): http://www.gnu.org/software/binutils/ –

+5

no hay forma de hacer eso en C++. En GCC, sin embargo, hay una función expuesta por el ABI que sí lo hace. Está en cxxabi.h y se llama __cxa_demangle. solo pásalo por el nombre destrozado. Su interfaz sigue este ABI: http://www.codesourcery.com/public/cxx-abi/abi.html#demangler –

17

std::type_info::name() devuelve un nombre específico de aplicación. AFAIK, no hay una forma portátil de obtener un "buen nombre", aunque GCC has one. Mira abi::__cxa_demangle().

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

¡Gracias por esto! Fue una gran ayuda en mi proyecto actual. –

0

¿Hay una solución portátil

solución sería hacer una plantilla truco para devolver todos los nombres de los tipos harcoded como char*

la plataforma no tiene #include <cxxabi.h>?

+1

Sin soporte especial de la clase en sí (como el método 'whoami()') cualquier "plantilla pirateada" solo puede generar un tipo * estático *, no el * dinámico * (considere un puntero a la clase base polimórfica). –

+0

Qt proporciona un mecanismo de reflexión muy agradable con su sistema de metaobjetos. Lo recomiendo mucho –

Cuestiones relacionadas