C++ 如何从C++;对象

C++ 如何从C++;对象,c++,class,C++,Class,是否也可以获取对象名称 #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(

是否也可以获取对象名称

#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";
}
<> >强> C++提供了实现这一点的机制吗?< /强>

< p>您可以尝试使用.< 这不适用于“对象”名称,但您知道对象名称,因此您只需将其存储在某个位置即可。编译器不关心您为对象命名了什么

但是,值得记住的是,typeid的输出是特定于编译器的,因此即使它在当前平台上生成您想要的内容,也可能不会在其他平台上生成。这对你来说可能是个问题,也可能不是

另一种解决方案是创建某种类型的模板包装器,将类名存储在其中。然后,您需要使用部分专业化来让它为您返回正确的类名。这具有可在编译时工作的优点,但要复杂得多

编辑:更加明确

template< typename Type > class ClassName
{
public:
    static std::string name()
    {
        return "Unknown";
    }
};
最后,要获取类名,请执行以下操作:

template<> class ClassName<MyClass>
{
public:
    static std::string name()
    {
        return "MyClass";
    }
};
ClassName< MyClass >::name();
可按如下方式进行宏操作:

#define DefineClassName( className ) \
\
template<> class ClassName<className> \
{ \
public: \
    static std::string name() \
    { \
        return #className; \
    } \
}; \
std::string classname()
{
     return "MyClass";
}
DefineClassName( className ) \
std::string classname()  \
{ \
     return #className; \
}
那你就干脆放弃吧

DefineClassName( MyClass );
在您定义的类中…

使用
typeid(类)。name

//假设所有包含/名称空间等的插图代码

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

struct A{};
int main(){
   cout << typeid(A).name();
}
#包括
#包括
使用名称空间std;
结构A{};
int main(){

您是否希望[classname]为“一”,而[objectname]为“一”


如果是这样的话,这是不可能的。这些名称只是程序员的抽象,并没有在生成的二进制代码中实际使用。您可以给类一个静态变量classname,将其设置为“一”,然后给类一个普通变量objectname,您可以通过方法或构造函数直接分配。然后您可以查询这些方法的类名和对象名。

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

#include <iostream>
#define quote(x) #x
class one {};
int main(){
    one A;
    std::cout<<typeid(A).name()<<"\t"<< quote(A) <<"\n";
    return 0;
}
在我的机器上,
#
在对行进行预处理后,将令牌更改为字符串

std::cout<<typeid(A).name()<<"\t"<< "A" <<"\n";
因为编译器不会跟踪所有变量的名称

正如在gcc中发生的那样,typeid()的结果。name()是损坏的类名,以获得使用

#包括
#包括
#定义引号(x)#x
模板类一{};
int main(){
一个A;
智力状态;
char*demangled=abi::_cxa_demangle(typeid(A).name(),0,0和status);

std::cout只需编写简单的模板:

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

struct A {} a;

void main() {
   std::cout << getClassName(a);
}
模板
常量字符*getClassName(T){
返回typeid(T.name();
}
结构A{}A;
void main(){

std::cout对@Chubsdad答案的改进

//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();
}

要在不损坏内容的情况下获取类名,可以在构造函数中使用func宏:

class MyClass {
    const char* name;
    MyClass() {
        name = __func__;
    }
}
您可以尝试以下方法:

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
模板
内联常量字符*getTypeName(){
返回typeid(T.name();
}
#定义类型名称(类型、类型名称)\
模板\
内联常量char*getTypeName(){\
返回类型名称\
}
定义类型名称(int,“int”)
定义类型名称(浮动,“浮动”)
定义类型名称(双精度,“双精度”)
定义类型名称(标准::字符串,“字符串”)
定义类型名称(bool,“bool”)
定义类型名称(uint32“uint”)
定义类型名称(uint64“uint”)
//添加自定义类型的定义
这样称呼它:

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

STD::我很困惑。你是否用一个“类学生”来联系C+++代码>类< /代码>?如果你有一个<代码>类< /代码>代表一个类,这个类有一个名字,比如“Gutentag太太的幼儿园”。它应该有一个数据成员将其存储为
std::string
@Potatoswatter:现在,我很困惑。你在问什么?单词“class”有两种含义而且有学生的类不是
class
关键字所指的类。@Potatoswatter:哦,我明白了。不,我只想在这里检索
class
名称,即
one
。我建议不要允许默认类名,因为它违背了目的。如果我们想命名类,那么就在每个类上强制使用它。是的很公平。有些人可能更喜欢它与任何类甚至其他类一起工作。我猜你的意思是#className而不是###className?是的……对不起……当时我没有一台可以测试编译的机器。@chubsdad:你期望的输出是什么?我得到了
1A
,但正如你所指出的那样,类名是
one
@Lazer:t、 这将打印一个实现定义的字符串。如果您想要更奇特的方式,请参考我的编辑网站“不能保证同一类型上的typeid表达式的所有求值都会返回相同的std::type_info实例”。这意味着
&typeid(a)==&typeid(a)
可以是
false
。使用C++11可以使用。可能使用的哈希值更好,例如typeid(A)。hash_code()为什么我们会得到
3one
?什么是
3
?@Lazer不知道,正如人们所说,
typeid
的结果是特定于平台的。这可能与C++的名称篡改方案有关。如果我尝试
模板类一{};
并使用
one
我得到
3oneIiE
作为类名,因此它确实与名称损坏有关(这可能意味着类具有
3
字符名
one
I
一个模板参数
I
(int)
E
参数结束)+1我不知道我们甚至在C++中有这样的功能,“3”可能是名称“1”的长度这个名字没有提供任何理由想要检索名称<代码>一个<代码>。这就是我在问题讨论中所要问的。想要一个C++类的名字与丑陋的动态类型黑客相关联,并且调试。不是运行时类型信息的一个工作。@ PATATOSWATER:它与您所建议的类无关。例如,如果我有一个变量<代码> int A;< /C> >,是否有一个C++中的构造允许我做类似于<代码>的事情(如果(a)类型()
3one B
#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
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*
class MyClass {
    const char* name;
    MyClass() {
        name = __func__;
    }
}
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
void main() {
 std::cout << getTypeName<int>();
}