2010-12-16 22 views
12

Si he definido una clase:¿Cómo obtener el nombre de clase?

class Blah {}; 

¿Cómo puede I:.

std::string const className = /* What do I need to do here? */; 
assert(className == "Blah"); 

no creo typeid() nombre() es una buena idea ya que es compiler implementation específica. ¿Hay algo provisto por el estándar C++ o Boost?

Nota: Si la clase se heredara del QObject de Qt, podría usar fácilmente QMetaObject::className() para obtener el nombre de clase.

Respuesta

10

De esta manera:

class Blah { static std::string const className() { return "Blah"; }}; 

std::string const name = Blah::className(); 
assert(name == "Blah"); 

O esto:

class Blah {}; 

template < typename T > struct name; 
template < > struct name<Blah> { static std::string value() { return "Blah"; }}; 

std::string const classname = name<Blah>::value(); 
assert(classname == "Blah"); 

Fancier:

#define DECLARE_NAMED_CLASS(Name) \ 
struct Name;\ 
template < > struct name<Name> { static std::string value() { return #Name; }};\ 
struct Name 

DECLARE_NAMED_CLASS(Blah) {}; 
std::string const className = name<Blah>::value(); 
... 

O esto:

class Blah : QObject { Q_OBJECT }; 

O esto: ... O esto: ...

+6

Otra solución sería TypeId() + demangle. De lo contrario, ¿cómo podría manejar los espacios de nombres, etc.? –

+2

typeid no garantiza que no se pueda registrar. – quetzalcoatl

+0

El primer caso es el único serio. Es legible, fácil de mantener y usar. El segundo explica un problema simple. ¿Quizás prefiera utilizar una API REST para llamar a un servicio web? El tercero es considerado como un mal hábito. Cuando se trata de un buen diseño, el preprocesador es el peor y lo último que debe utilizar. Los únicos pocos casos de uso razonables para preprocesadores que puedo pensar es pragma una vez. – nali

1

No creo que haya ninguna solución específica no compiladora para tal problema que no involucre un montón de macros en la declaración de clase (de hecho, si entendí correctamente la documentación QT, la cadena que obtiene con objectName está realmente asignada "por mano ", creo que con código creado por moc).

Por otro lado, en general, para verificar si la clase de un objeto es una que no desea, no debe hacer una comparación de cadenas, sino realizar una comparación tipográfica.

assert(typeid(YourObject)==typeid(Blah)); 

Pero probablemente deberías explicar mejor lo que estás tratando de lograr.

3

Probar una clase al ver su nombre suena terriblemente como un enfoque de estilo Java para mí, y en C++, debe tener cuidado de intentar aplicar el mismo ¡patrones! Una forma mejor sería usar algo como boost::type_traits, y puede ser is_same, con el nombre de clase real.

1

Creo que un dynamic_cast puede ser lo que estás buscando. No le da el nombre de la clase, pero falla en la forma en que le gustaría que fallara su aserción, excepto que las subclases de Blah no se detectarán.

1

I dont think typeid(). Name() es una buena idea ya que es compilador implementación específica.

Sí, el estándar no requiere de implementación para usar nombres específicos, por lo que puede cambiar incluso para el mismo compilador.

¿Hay algo provisto por el estándar C++ o Boost?

No hay instalaciones estándar que devuelvan el nombre de la clase en alguna forma canónica.

1

El método QObject-> meta objeto() es válido para Qt, excepto las clases basadas QGraphicsItem que no se heredan de QObject ...

Cuestiones relacionadas