-1

私は自分の理解のために以下のプログラムを実装しました。しかし、typeid によって返されるクラス名が少し変更されていることがわかります。名前マングリングが原因である可能性があることはわかっていましたが、 extern C を含めても役に立ちません。

誰かがそのような動作の理由とそれを修正する方法を理解するのを手伝ってもらえますか?

g++ バージョン - 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.

プログラムで指定されているクラス名を期待していました。

どうもありがとう。

4

2 に答える 2

3

type_info::name()どのように見えるかについての要件はありません。

式の結果は、typeid静的型const std::type_info(18.7.1) および動的型 の左辺値であるconst std::type_infoconst name、名前がパブリックに派生した実装定義のクラスです。 std::type_info

次に、約std::type_info::name()

const char* name() const;

戻り値:実装定義の NTBS。

[...]

NTBSは、null で終わるバイト文字列の省略形です。

つまり、 の値に依存しないでくださいtype_info::name()

g++ で実際に表示される内容:

これらの名前はマングルされた名前であり、そのようなマングルされた名前の g++ の実装は、長さがプレフィックスされた文字列に基づいています。ここで、各部分文字列は名前空間名とその他の情報です。しかし、それは基本的にそれだけです。

例えば:

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

後者の 2 つは、名前が異なることに依存することさえできないことを示しています。

于 2013-04-17T05:47:28.347 に答える
2

名前の「デマングリング」に関心がある場合、g++ にはこれを行うためのコンパイラ固有の関数があります。

http://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.htmlで例を見つけることができます

于 2013-04-17T06:28:31.297 に答える