1

私がこのコードを持っていると仮定しましょう。

class Ingredients{
    public:
        Ingredients(int size,string name);
        int getsize();
    private:
        string name;
        int size;
};

struct Chain{
    Ingredients* ing;
    Chain* next;  
}

そして私のメインでは;

int main()
{
    cout<<typeid(Chain).name()<<endl;
    cout<<typeid(Chain->ing).name()<<endl;
    cout<<typeid(Chain->next).name()<<endl; 

}

私のヘッダーは;

#include <iostream>
#include <typeinfo>

using namespace std;

そして最後に出力します。

P8Chain
P12Ingredients
P8Chain

だから私の質問は、このタイプはコードでそれを使用するのに信頼できるでしょうか?タイプがコンピューターからコンプに変更されている場合(P8とP12の問題のため、同じかどうかはわかりません)。このタイプは信頼できません。あなたの意見は何ですか?

また、実行ごとに変更されるわけではありません。

4

4 に答える 4

3

これらはコンパイラに依存するため、コード内で使用しないでください。

C ++標準では、typeidセクション5.2.8)に関して次のように述べています。

式の結果は、静的型と動的型または名前typeidの左辺値です。ここで、nameは、から派生した実装定義のクラスです。const std::type_infoconst std::type_infoconst std::type_info

ある種のRTTIが必要な場合にできること

if (typeid(myobject) == typeid(Chain)) {
    do_something();
}
于 2012-11-02T22:00:19.483 に答える
3

それはあなたが「タイプ」によって何を意味するかによります。タイプの多かれ少なかれ標準的な定義は、タイプが取ることができる値と操作のセットであり、サイズintまたは文字列の最大長が変わるため、これはマシンごとに変わります。一方、型はコンパイラとC ++標準がそれを考慮しているものであり、非常に大まかに対応するか、少なくともスコープ名で識別されるという非常に現実的な意味があります。最後に、std::type_info::name()関数は大幅に指定されていません。せいぜい、デバッグに役立つ可能性があり(たとえば、関数が呼び出された実際の派生クラスをログに記録する)、すべてのコンパイラがそれを提供するわけではありません。標準に関する限り、コンパイラは常に空の文字列を返すことができますが、それでも準拠しています。

于 2012-11-02T22:19:31.033 に答える
1

規格によれば、name()は実装定義されています(Stroustrupの本によると-第3版の415ページを参照)

于 2012-11-02T22:08:21.023 に答える
1

「タイプ」という言葉には複数の意味があります。

型理論の観点から、C++構造体は実際には型をまったく定義していません。

さらに便利なことに、C ++言語標準では、用語を厳密に定義していなくても、厳密に解釈できる方法で型について説明しています。これらの用語では、構造体宣言は一意で一貫性のある型を定義します。

おそらくさらに便利なことに、C ++コンパイラ(およびCリンカ)にとって、型は、メモリレイアウト、マングル名、メンバー名と型のリスト、特別な通常のメンバー関数へのポインタ、場合によってはvtableへのポインタなどで表されます。および/またはrtti情報など。これは実装ごとに同じではありません。同じ実装のビルド間では、関連するコードが変更されていなくても、一部の詳細(ポインターが指す場所など)が変更される場合がありますが、変更されない「タイプ」と便利に呼び出すことができる情報の有用なサブセットを定義できます。

それを超えると、type_info標準のセクション18.5.1で定義されたインスタンスは、明示的に定義された範囲内で変更できず、typeidセクション5.2.8で定義された結果は、そのインスタンスまたはそれと同等に比較される互換性のあるオブジェクトであると見なされます。 。type_infoしたがって、 2つの異なる実行から同時にインスタンスをロードすることが可能である場合、operator==を返す必要があるように思えますtrue。ただし、実際にtype_infoは2つの異なる実行からインスタンスをロードすることはできません(たとえば、インスタンスをシリアル化できる必要はありません)。したがって、これは関係がない場合があります。

最後に、typeid().name()セクション18.5.1で定義されているように、で表示される名前は、実装で定義されたNTBSです。ビルド、実行、同じ実行内の呼び出しの間で変更される可能性があります。常に空である可能性があります。実際には、それはデバッグに漠然と役立つものになることがよくありますが、それは保証されていません。たとえそうであったとしても、「デバッグに漠然と役立つ」は「実行および実行間で永続的」。

特定のコンパイラについて質問している場合、コンパイラのドキュメントには、標準で要求されているよりも厳しい保証が記載されている場合があります。たとえば、さまざまなプラットフォームで、g++はCodeSourceryで定義されたC++ ABIを使用することを保証し、マイナーコンパイラバージョン内のABIバージョンを変更せず、ABIで定義されたマングル名を名前として使用すると思いますtype_info。つまり、バイナリを別のコンピューターに移動しても名前に影響はなく、同じプラットフォームとg++バージョンを備えた別のコンピューターでソースを再コンパイルしても名前には影響しません。

于 2012-11-02T22:41:20.150 に答える