【问题标题】:typeid() returns extra characters in g++typeid() 在 g++ 中返回额外的字符
【发布时间】:2010-10-21 19:45:58
【问题描述】:
class foo
{
public:
  void say_type_name()
  {
    std::cout << typeid(this).name() << std::endl;
  }
};

int main()
{
  foo f;;
  f.say_type_name();
}

上面的代码使用 g++ 在我的 ubuntu 机器上打印 P3foo。我不明白为什么它打印 P3foo 而不仅仅是 foo。如果我像

这样更改代码
    std::cout << typeid(*this).name() << std::endl;

它打印 3foo

有什么想法吗?

【问题讨论】:

    标签: c++ g++ name-mangling typeid


    【解决方案1】:

    因为它是指向 foo 的指针。 foo 有 3 个字符。所以它变成了P3foo。另一个的类型为foo,因此它变为3foo。请注意,文本是依赖于实现的,在这种情况下,GCC 只是为您提供了内部的、错位的名称。

    在程序c++filt 中输入该损坏的名称以获得未损坏的名称:

    $ c++filt -t P3foo
    foo*
    

    【讨论】:

    • 哇!有趣的。还有两个问题.. 1 - c++filt 是 gcc 发行版的一部分还是 LINUX 的一部分? 2 - 有没有办法获得方法或类的重名?
    • c++filt 是 binutils 的一部分(ld(链接器)和 readelf 等其他小工具也来自该软件包):gnu.org/software/binutils
    • 在 C++ 中无法做到这一点。然而,在 GCC 中,有一个由 ABI 公开的函数可以执行此操作。它在 cxxabi.h 中并称为 __cxa_demangle 。只需将其传递给损坏的名称即可。它的界面遵循这个 ABI:codesourcery.com/public/cxx-abi/abi.html#demangler
    • 还要记住 typeid().name() 的结果将取决于实现。我不相信它甚至要求它产生一些可理解的东西,人类可读性要低得多。
    • 我相信 visual c++ 甚至会产生人类可读的字符串。但确实没有要求。许多关于 type_info 的事情都没有指定(在 C++ 标准的 18.5.1 中有描述)。
    【解决方案2】:

    std::type_info::name() 返回实现特定的名称。 AFAIK,虽然 GCC has one,但没有可移植的方式来获得“好”的名称。看abi::__cxa_demangle()

    int status;
    char *realname = abi::__cxa_demangle(typeid(obj).name(), 0, 0, &status);
    std::cout << realname;
    free(realname);
    

    【讨论】:

    • 谢谢!这对我目前的项目帮助很大。
    【解决方案3】:

    有没有便携的解决方案

    解决方法是制作一个模板以将所有硬编码类型名称返回为char*

    哪个平台没有#include &lt;cxxabi.h&gt;

    【讨论】:

    • 如果没有类本身的特殊支持(如whoami() 方法),任何“模板破解”都只能输出 static 类型,而不是 dynamic 一个(考虑一个指向多态基类的指针)。
    • Qt 通过它的元对象系统提供了一个非常好的反射机制。我强烈推荐它。
    猜你喜欢
    • 1970-01-01
    • 2016-05-13
    • 2010-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-29
    • 1970-01-01
    相关资源
    最近更新 更多