c++ - 如何从 C++ 对象中获取类名?

是否可以获取对象名称?


#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";
}

在哪里我可以获取像下面的名字:


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

C++是否提供了实现此功能的机制?

时间:

你可以使用预处理器显示变量的名称。 例如


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

输出


3one A

在我的计算机上。在预处理该行之后,#将标记更改为字符串,


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


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

你会得到

 
3one B

 

编译器不会跟踪变量的所有名称。

在gcc中,typeid().name()的结果是受损的类名,


#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;
}

给了我


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

其他编译器可能使用不同的命名方案。

使用typeid(class).name

代码假设所有的includes/namespaces等


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

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

重要的是要记住,这给了实现定义的名称。

据我所知,没有办法在运行时可靠地获取对象的名称,例如,代码中的'A '。

编辑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)];
}

是否[ classname]为'one'和[ objectname]要'A'?

如果是这样,这是不可能的。 这些名称只抽象为程序员实际使用,并且不在生成的二进制代码中。 可以为类提供一个静态变量classname,将该属性设置为'one'和普通变量objectname应指派就直接通过方法或构造函数。 然后你可以查询这些方法对事件类或对象名称。

你可以尝试使用"typeid "。


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

然后对于每个类执行:


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

它甚至可以是宏,如下所示:


#define DefineClassName( className ) 

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

简单地说,允许你去


DefineClassName( MyClass );

最后,要获得你的类名称,请执行以下操作:


ClassName< MyClass >::name();


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

可以是宏,如下所示:


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

那你就只需drop


DefineClassName( MyClass );

只需编写简单的模板:


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

struct A {} a;

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


//main.cpp

using namespace std;

int main(){
A a;
a.run();
}

//A.h
class A{
public:
 A(){};
 void run();
}

//A.cpp
#include <iostream>
#include <typeinfo>
void A::run(){
 cout << (string)typeid(this).name();
}

它将打印:

 
class A*

 
...