使用typeid时获取不正确的类名 -

时间:2013-04-17 05:24:32

标签: c++ typeid

我已经实施了以下程序以供我自己理解。但是我看到typeid返回的类名略有修改。我知道这可能是因为名称损坏,但包括外部C也无济于事。

有人可以帮助我理解为什么会出现这种行为以及如何解决这个问题?

g ++ version - 4.7.0

#include <iostream>
#include <typeinfo>

using namespace std;

class Base
{
    public:
        virtual ~Base(){}
};

class Derive : public Base
{
    public:
        ~Derive(){}
};

class newBase
{
    public:
        ~newBase(){}
};

class newDerive : public newBase
{
    public:
        ~newDerive(){}
};

int main()
{
    Base base;
    Derive derive;
    Base *pBase;
    Base & rBase1 = base;
    Base & rBase2 = derive;

    newBase newbase;
    newDerive newderive;
    newBase *pNewBase;

    //Results with polymorphic class.
    pBase = &base;
    cout<<"Base class pointer pBase contains object of type "<<typeid(*pBase).name()            <<".\n";

    pBase = &derive;
    cout<<"Base class pointer pBase contains object of type "<<typeid(*pBase).name()<<".\n";

    cout<<"\nReference variable rBase1 referring to "<<typeid(rBase1).name()<<".\n";
    cout<<"Reference variable rBase2 referring to "<<typeid(rBase2).name()<<".\n";

    //Results with non-polymorphic class.
    pNewBase = &newbase;
    cout<<"\nBase class pointer pNewBase contains object of type "<<typeid(*pNewBase).name()<<".\n";

    pNewBase = &newderive;
    cout<<"Base class pointer pNewBase contains object of type "<<typeid(*pNewBase).name()<<".\n";

    return 0;
}

Output -
Base class pointer pBase contains object of type 4Base.
Base class pointer pBase contains object of type 6Derive.

Reference variable rBase1 referring to 4Base.
Reference variable rBase2 referring to 6Derive.

Base class pointer pNewBase contains object of type 7newBase.
Base class pointer pNewBase contains object of type 7newBase.

我期待在程序中指定的类名。

非常感谢。

2 个答案:

答案 0 :(得分:3)

type_info::name()的外观没有要求。

  

typeid表达式的结果是静态类型const std::type_info(18.7.1)和动态类型的左值   const std::type_infoconst name其中name是公开派生自的实现定义类   std::type_info

然后,关于std::type_info::name()

  

const char* name() const;

     

返回:实现定义的NTBS。

     

[...]

NTBS 只是以空字符结尾的字节字符串的简写。

换句话说:您不应该依赖type_info::name()的任何值。

你用g ++实际看到了什么:

这些名称是mangled names,而g ++对这些受损名称的实现基于length-prefixed strings,其中每个子字符串都是命名空间名称,加上其他一些信息;但基本上就是这样。

例如:

unmangled: foo::bar::Frob
mangled:   3foo3bar4Frob

放入编译器的示例:

#include <iostream>
#include <typeinfo>

namespace foo { namespace bar { 
    enum Frob {};
    class Frobnicate {};
    Frob frob;

    template <typename T> void Meh() { throw T(); }
} }

int main () {
    std::cout << typeid(foo::bar::Frob).name() << '\n'
              << typeid(foo::bar::Frobnicate).name()  << '\n'  
              << typeid(foo::bar::frob).name() << '\n'
              << typeid(foo::bar::Meh<int>).name() << '\n'
              << typeid(foo::bar::Meh<float>).name() << '\n'
    ;
}

为我输出:

N3foo3bar4FrobE
N3foo3bar10FrobnicateE
N3foo3bar4FrobE
FvvE
FvvE

后两者告诉你,一个人甚至不能依赖于不同的名字。

答案 1 :(得分:2)

如果您对&#34; demangling&#34;感兴趣名称,g ++有一个特定于编译器的函数来执行此操作。

您可以在http://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html

中找到示例
相关问题