11

Andrei AlexandrescuはModern C++ Designで次のように書いています。

によって返されるオブジェクトにtypeidは静的ストレージがあるため、有効期間の問題について心配する必要はありません。

アンドレイは続けます:

標準では、たとえば の各呼び出しが同じオブジェクトtypeid(int) への参照を返す ことは保証されていません。type_info

標準ではこれが保証されていませんが、GCC や Visual Studio などの一般的なコンパイラではどのように実装されているのでしょうか?

typeidリークしない (そして呼び出しごとに新しいインスタンスを返す)と仮定すると、それはアプリケーションごと、翻訳単位ごと、dll/so ごと、またはまったく異なるものごとに 1 つの「テーブル」ですか?

ときはあり&typeid(T) != &typeid(T)ますか?

私は主に Windows 用のコンパイラに興味がありますが、Linux やその他のプラットフォームに関する情報も歓迎します。

4

2 に答える 2

11

&typeid(T)!=&typeid(T)の場合はありますか?

私は主にWindows用のコンパイラに興味がありますが、Linuxやその他のプラットフォーム用の情報もありがたいです。

はい。したがって、Windowsでは、DLLに未解決のシンボルを含めることはできません。あなたが持っている場合:

foo.h

struct foo { virtual ~foo() {} };

dll.cpp

#include "foo.h"
...
foo f;
cout << &typeid(&f) << endl

main.cpp

#include "foo.h"
...
foo f;
cout << &typeid(&f) << endl

あなたに異なるポインタを与えるでしょう。dllがロードされる前にtypeid(foo)がdllとプライマリexeの両方に存在する必要があるため

さらに、Linuxでは、メインの実行可能ファイルが-rdynamic(または--export-dynamic)でコンパイルされていない場合、typeidは実行可能ファイルと共有オブジェクト(通常はELFプラットフォームでは発生しません)で異なるシンボルに解決されます。実行可能ファイルをリンクするときに行われるいくつかの最適化-不要なシンボルの削除。

于 2009-12-28T10:20:13.387 に答える
1

標準では、実装にある程度の自由を与えるために、特定の動作が指定されていないことがあります。この場合、TypeID がどのように管理されるかはコンパイラの実装に任されており、単純に一連の規則が与えられているだけです (基本的に、このメモリがどのように割り当てられているかは気にしないでください)。

メモリ アドレスに基づいて TypeId を比較できるようにする必要がある特定の理由はありますか? TypeId は既に == と != をオーバーライドして、それらを比較する機能を提供し、それらを一意に識別するために使用できる name() を提供します。

The C++ Programming Language (Bjarne Stroustrup) を利用できる場合は、第 15 章にクラス階層の処理に関する多くの詳細があります。そこに別の解決策が見つかるかもしれませんか?

于 2009-11-30T11:06:18.397 に答える