以编程方式检索c ++类名

时间:2009-06-21 20:06:02

标签: c++ class macros

我想知道在C ++中是否有可能以字符串形式检索类的名称,而不必将其硬编码到变量或getter中。我知道这些信息实际上并没有在运行时使用,因此它不可用,但有没有可用于创建此功能的宏?

编辑:可能有助于注意我实际上是在尝试检索派生类的名称,而我正在使用Visual C ++ 2008 Express Edition。

5 个答案:

答案 0 :(得分:88)

您可以使用typeid

#include <typeinfo>
cout << typeid(obj).name() << endl;

但是,这是不鼓励的,因为格式不是标准化的,并且可能在不同的编译器(甚至同一编译器的不同版本)之间有所不同。

答案 1 :(得分:35)

如果你只想检查它是否属于某个类,那么

typeid(obj) == typeid(CSubClass)
无论实现如何,

始终有效。

否则,一种方便的方法是声明:

virtual const char* classname() { return "CMyClass";}

并实现每个子类。

答案 2 :(得分:10)

typeid(obj).name()事物总是给出声明的变量类型,而不是对象的实际类型(类)。如果将变量obj分配给obj被声明为的类的子类的实例,则不幸的是,typeid不会显示该内容。

答案 3 :(得分:1)

这是什么,

在Windows 10上使用Visual Studio 2019(v142)进行了测试。

#include <iostream>
#include <typeinfo>
#include <string>

/**
 @author    blongho
 @fn        template<typename Object> std::string classNameOf()

 @brief     Determine the class name of an object

 @tparam    Object  Type of the object.

 @returns   A name of the class
 @date      2019-09-06
 */

template<typename Object>
std::string classNameOf() {
    std::string name = typeid(Object).name(); //* user defined types gives "class Type"*\ 
    size_t spacePosition = name.find_first_of(" ");
    if (spacePosition != std::string::npos) {
        return name.substr(spacePosition + 1, name.length());
    }
    return name; // mostly primitive types
}


class Person {
private:
    /* data */
public:
    Person() {};
    ~Person() {};

};

class Data
{
private:
    /* data */
public:
    Data() {};
    ~Data() {};

};

struct Type {};

int main() {
    std::cout << "Class name of Person() is \"" << classNameOf<Person>() << "\"\n";
    std::cout << "Class name of Data() is \"" << classNameOf<Data>() << "\"\n";
    std::cout << "Class name of Type() is \"" << classNameOf<Type>() << "\"\n";
    std::cout << "Class name of double is \"" << classNameOf<double>() << "\"\n";
    std::cout << "Class name of std::string is \"" << classNameOf<std::string>() << "\"\n";
    std::cout << "Class name of int is \"" << classNameOf<int>() << "\"\n";
    std::cout << "Class name of float is \"" << classNameOf<float>() << "\"\n";
    std::cout << "Class name of char is \"" << classNameOf<char>() << "\"\n";
    return 0;
}

Output

Class name of Person() is "Person"
Class name of Data() is "Data"
Class name of Type() is "Type"
Class name of double is "double"
Class name of std::string is "std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >"
Class name of int is "int"
Class name of float is "float"
Class name of char is "char"

在Ubuntu 18.04中,

g++ -o test src/main.cpp
./test
Class name of Person() is "6Person"
Class name of Data() is "4Data"
Class name of Type() is "4Type"
Class name of double is "d"
Class name of std::string is "NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE"
Class name of int is "i"
Class name of float is "f"
Class name of char is "c"

答案 4 :(得分:0)

使用C ++ 17和third-party library,您现在可以获得类似的类的名称

#include <iostream>
#include "nameof.hpp"

namespace test {
    class Object {};
}

int main() {
    constexpr auto obj_name = nameof::nameof_type<test::Object>();
    std::cout << obj_name << std::endl;
    // this prints "test::Object"
}

这仅使用编译时信息,因此可以为constexpr。请注意,它不是便携式的;例如不支持英特尔的编译器。