2008-07-31
C++ のtype_info.name()
C++ではRTTIと呼ばれる機構によって,実行時の型情報が取得できる.
これによって,動的に定まるオブジェクトの型を知ることができる.
#include <typeinfo>
#include <stdio.h>
namespace test{
class A {
public:
virtual void m(){} // 1. 仮想メソッド宣言
};
class B : public A {
public:
virtual void m(){} // 1. 仮想メソッド宣言
};
}
using namespace test;
main(){
A * a0;
a0 = new A();
const std::type_info & id = typeid(*a0);
printf("%s\n", id.name());
a0 = new B();
const std::type_info & id2 = typeid(*a0);
printf("%s\n", id2.name());
}
こんなコードを書いて,g++4.0で実行してみると
N4test1AE N4test1BE
という結果がでる.これらはtest::A, test:Bをマングリングしたものである.ちなみに,typeidは多相的な型でないとうまく機能しない.これは実行時型情報が典型的にはオブジェクトの仮想関数テーブルに収められるためである.例えば,上のコードで「仮想メソッド宣言」とコメントのついた2行を削除するとAとBは多相的でなくなるため,結果が変わってしまう.
N4test1AE N4test1AE
Visual C++では
type_info.name() で型の名前が取得できるが,この値のフォーマットは,仕様で規定されていない.従って,コンパイラ依存となっている.上記のコードをVisual C++ 2008 expressで実行すると,
class test::A class test::B
となる.したがって,コンパイラが異なるシステムで型情報をやりとりするには,このあたりをちゃんと吸収してやらなければならないわけだ.
マングリングとは
さて,g++で出てくる謎めいた文字列をどうやってデコードしたもんだろう? マングリングに関してはwikipediaにいい記事があった.が,コンパイラに非常に強く依存しているようなので,一筋縄では行かない.
どうせコンパイラに依存しているのであれば,コンパイラの提供しているライブラリを使えばいい,という説も.
こちらの記事によるとg++には__cxa_demangleという関数がありこれをつかえばよいとのこと.
extern "C" char *__cxa_demangle (
const char *mangled_name,
char *output_buffer,
size_t *length,
int *status);
std::string demangle(const char * name) {
size_t len = strlen(name) + 256;
char output_buffer[len];
int status = 0;
return std::string(
__cxa_demangle(name, output_buffer,
&len, &status));
}
こうしておいて,
a0 = new A();
const std::type_info & id = typeid(*a0);
printf("%s\n", demangle(id.name()).c_str());
こうすると
test::A
が得られる.めでたし?
トラックバック - http://d.hatena.ne.jp/hidemon/20080731/1217488497
リンク元
- 4 http://reader.livedoor.com/reader/
- 2 http://diaspar.jp/node/183
- 2 http://www.google.co.jp/search?q=json-py&sourceid=navclient-ff&ie=UTF-8&rlz=1B3GGGL_jaJP256JP256
- 2 http://www.google.com/reader/view/
- 1 http://72.14.235.104/search?q=cache:_L3VwCt-A80J:d.hatena.ne.jp/hidemon/20080629/1214730669+Python+Class ディクショナリ&hl=ja&ct=clnk&cd=8&gl=jp&lr=lang_ja&client=firefox-a
- 1 http://d.hatena.ne.jp/diarylist?of=0&mode=rss&type=public
- 1 http://d.hatena.ne.jp/keyword/C++
- 1 http://d.hatena.ne.jp/keyworddiary/C++
- 1 http://d.hatena.ne.jp/wiseler/20080801/p1
- 1 http://d.hatena.ne.jp/ytakamiya/