¿Cómo puedo obtener el nombre de la clase de un objeto C++?

7 minutos de lectura

¿Como puedo obtener el nombre de la clase de un
láser

¿Es posible obtener el nombre del objeto también?

#include<cstdio>

class one {
public:
    int no_of_students;
    one() { no_of_students = 0; }
    void new_admission() { no_of_students++; }
};

int main() {
    one A;
    for(int i = 0; i < 99; i++) {
        A.new_admission();
    }
    cout<<"class"<<[classname]<<" "<<[objectname]<<"has "
        <<A.no_of_students<<" students";
}

donde puedo buscar los nombres, algo como

[classname] = A.classname() = one
[objectname] = A.objectname() = A

¿C++ proporciona algún mecanismo para lograr esto?

  • Estoy confundido. ¿Estás relacionando C++? class con una “clase de estudiantes”? Si tienes un class que representa una clase, y la clase tiene un nombre como “Jardín de infantes de la Sra. Gutentag”, debe tener un miembro de datos para almacenar eso como un std::string.

    – Patatas

    06 sep.


  • @Potatoswatter: Ahora, estoy confundido. ¿Que estas preguntando?

    – Lazer

    06 sep.

  • Hay dos significados para la palabra “clase”, y el tipo de clase que tiene estudiantes no es lo que el class la palabra clave se refiere.

    – Patatas

    06 sep.

  • @Potatoswatter: Oh, lo entiendo. No, solo quiero recuperar el class nombre es decir one aquí.

    – Lazer

    06 sep.

  • stackoverflow.com/questions/81870/…

    – Ciro Santilli

    01 ene.

1643415367 980 ¿Como puedo obtener el nombre de la clase de un
scott gales

Puede mostrar el nombre de una variable utilizando el preprocesador. Por ejemplo

#include <iostream>
#define quote(x) #x
class one {};
int main(){
    one A;
    std::cout<<typeid(A).name()<<"t"<< quote(A) <<"n";
    return 0;
}

salidas

3one    A

en mi maquina El # cambia un token en una cadena, después de preprocesar la línea es

std::cout<<typeid(A).name()<<"t"<< "A" <<"n";

Por supuesto, si haces algo como

void foo(one B){
    std::cout<<typeid(B).name()<<"t"<< quote(B) <<"n";
}
int main(){
    one A;
    foo(A);
    return 0;
}

conseguirás

3one B

ya que el compilador no realiza un seguimiento de todos los nombres de las variables.

Como sucede en gcc, el resultado de typeid().name() es el nombre de la clase destrozada, para obtener el versión desgarrada usar

#include <iostream>
#include <cxxabi.h>
#define quote(x) #x
template <typename foo,typename bar> class one{ };
int main(){
    one<int,one<double, int> > A;
    int status;
    char * demangled = abi::__cxa_demangle(typeid(A).name(),0,0,&status);
    std::cout<<demangled<<"t"<< quote(A) <<"n";
    free(demangled);
    return 0;
}

que me da

one<int, one<double, int> > A

Otros compiladores pueden usar diferentes esquemas de nombres.

  • ¿Por qué conseguimos 3one? Qué es 3?

    – Lazer

    06 sep.

  • @Lazer No tengo idea, como dice la gente, el resultado de typeid es específico de la plataforma. Probablemente tenga algo que ver con el esquema de manipulación de nombres de C++.

    – Scott Gales

    06 sep.

  • si lo intento template <typename T> class one{}; y usa un one<int> yo obtengo 3oneIiE como el nombre de la clase, por lo que de hecho tiene que ver con la manipulación de nombres (el material probablemente significa clase con un 3 Nombre del personaje one con I un argumento de plantilla i (En t) E fin de los argumentos)

    – Scott Gales

    06 sep.


  • +1 No sabía que incluso tenemos esa funcionalidad en C++

    – mukeshkumar

    06 sep.

  • “3” es probablemente la longitud del nombre “uno”. La manipulación de nombres antepone las longitudes a los nombres.

    – Dra. Chandra

    31 oct.

1643415367 238 ¿Como puedo obtener el nombre de la clase de un
gordito

usar typeid(class).name

// código ilustrativo que asume todos los espacios de nombres/incluye, etc.

#include <iostream>
#include <typeinfo>
using namespace std;

struct A{};
int main(){
   cout << typeid(A).name();
}

Es importante recordar que esto le da a una implementación nombres definidos.

Hasta donde yo sé, no hay forma de obtener el nombre del objeto en tiempo de ejecución de manera confiable, por ejemplo, ‘A’ en su código.

EDITAR 2:

#include <typeinfo>
#include <iostream>
#include <map>
using namespace std; 

struct A{
};
struct B{
};

map<const type_info*, string> m;

int main(){
    m[&typeid(A)] = "A";         // Registration here
    m[&typeid(B)] = "B";         // Registration here

    A a;
    cout << m[&typeid(a)];
}

  • @chubsdad: ¿Cuál es el resultado que espera? yo obtengo 1Apero el nombre de la clase es one.

    – Lazer

    06 sep.

  • @Lazer: como se señaló, esto imprime una cadena definida por la implementación. Consulte mi edición si desea una forma más elegante

    – Gordito

    06 sep.


  • El sitio cppreference.com dice “No hay garantía de que todas las evaluaciones de la expresión typeid del mismo tipo devuelvan la misma instancia de std::type_info”. Esto significa &typeid(A) == &typeid(A) podría ser false. Con C++ 11 podrías usar std::type_index.

    – JojOatXGME

    25 oct.


  • probablemente se utilicen mejores valores hash, por ejemplo, typeid(A).hash_code()

    – Nick

    16 feb.

Para obtener el nombre de la clase sin manipular cosas, puede usar función macro en el constructor:

class MyClass {
    const char* name;
    MyClass() {
        name = __func__;
    }
}

  • este compilador si es específico. uno te dará MyClass::MyClass el otro MyClass. Cuando se usa en el método regular, producirá MyClass::SomeMethod o SomeMethod.

    – Marek R.

    31 jul.


Quieres [classname] ser ‘uno’ y [objectname] ser un’?

Si es así, esto no es posible. Estos nombres son solo abstracciones para el programador y en realidad no se usan en el código binario que se genera. Podría darle a la clase un nombre de clase de variable estática, que establezca en ‘uno’ y un nombre de objeto de variable normal que asignaría directamente, a través de un método o del constructor. A continuación, puede consultar estos métodos para los nombres de clase y objeto.

Solo escribe una plantilla simple:

template<typename T>
const char* getClassName(T) {
  return typeid(T).name();
}

struct A {} a;

void main() {
   std::cout << getClassName(a);
}

Podrías intentar usar “typeid”.

Esto no funciona para el nombre del “objeto”, pero USTED conoce el nombre del objeto, por lo que solo tendrá que almacenarlo en algún lugar. Al Compilador no le importa el nombre que hayas dado a un objeto.

Sin embargo, vale la pena tener en cuenta que la salida de typeid es algo específico del compilador, por lo que incluso si produce lo que busca en la plataforma actual, es posible que no lo haga en otra. Esto puede o no ser un problema para usted.

La otra solución es crear algún tipo de contenedor de plantilla en el que almacene el nombre de la clase. Luego, debe usar la especialización parcial para que le devuelva el nombre de clase correcto. Esto tiene la ventaja de trabajar en tiempo de compilación pero es significativamente más complejo.

Editar: ser más explícito

template< typename Type > class ClassName
{
public:
    static std::string name()
    {
        return "Unknown";
    }
};

Luego, para cada clase algo como lo siguiente:

template<> class ClassName<MyClass>
{
public:
    static std::string name()
    {
        return "MyClass";
    }
};

Que incluso podría ser macro’d de la siguiente manera:

#define DefineClassName( className ) 

template<> class ClassName<className> 
{ 
public: 
    static std::string name() 
    { 
        return #className; 
    } 
}; 

Permitiéndole, simplemente, hacer

DefineClassName( MyClass );

Finalmente, para obtener el nombre de la clase, haría lo siguiente:

ClassName< MyClass >::name();

Edit2: Elaborando más, necesitaría colocar esta macro “DefineClassName” en cada clase que cree y definir una función de “nombre de clase” que llamaría a la función de plantilla estática.

Edit3: Y pensando en ello… Obviamente es malo publicar a primera hora de la mañana, ya que también puede definir una función miembro “nombre de clase ()” de la siguiente manera:

std::string classname()
{
     return "MyClass";
}

que se puede macro’d de la siguiente manera:

DefineClassName( className ) 
std::string classname()  
{ 
     return #className; 
}

Entonces simplemente puede soltar

DefineClassName( MyClass );

en la clase como la defines…

¿Como puedo obtener el nombre de la clase de un
voltaje

Puedes probar esto:

template<typename T>
inline const char* getTypeName() {
  return typeid(T).name();
}

#define DEFINE_TYPE_NAME(type, type_name)  
  template<>                               
  inline const char* getTypeName<type>() { 
    return type_name;                      
  }

DEFINE_TYPE_NAME(int, "int")
DEFINE_TYPE_NAME(float, "float")
DEFINE_TYPE_NAME(double, "double")
DEFINE_TYPE_NAME(std::string, "string")
DEFINE_TYPE_NAME(bool, "bool")
DEFINE_TYPE_NAME(uint32_t, "uint")
DEFINE_TYPE_NAME(uint64_t, "uint")
// add your custom types' definitions

Y llámalo así:

void main() {
 std::cout << getTypeName<int>();
}

.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad