0
return *reinterpret_cast<UInt32*>((reinterpret_cast<char*>(this) + 2));

Struct は pragma pack 1 であり、uint、char、short フィールドの束が含まれています...

UInt32 であるため、最初に unsigned char* に reinterpret_cast する必要がありますか、それとも問題ですか?

また、ここでは速度が重要であり、reinterpret_cast は static_cast とは対照的にキャストの中で最速だと思います。

編集: 構造体は、実際には 2 つのシングルバイト フィールドで構成され、その後に約 16 個の他の構造体の結合が続きます。そのうちの 15 個は最初のフィールドとして UInt32 を持ちます。ないものではないことを簡単に確認してから、2 バイトのオフセットに reinterpret_cast を実行します。

4

4 に答える 4

4

メンバーに直接アクセスできませんか?これは未定義の動作であり、単語の配置を強制するシステムではまったく機能しません (これは、実行していることを考えるとおそらく問題ではありませんが、言及する必要があります)。

reinterpret_caststatic_castコンパイル時にメモリを使用する方法をコンパイラに伝えるだけなので、それほど高速ではありません。ただしdynamic_cast、遅くなります。

struct + offsetyourを非char型として扱う合法的な方法はありません。

于 2011-06-29T15:09:21.313 に答える
1

reinterpret_cast数値変換をstatic_cast実行する必要がない限り、同じランタイム(ゼロの隣)が必要です。使用するキャストは、「速度」ではなく、正確さに基づいて選択する必要があります。あなたが話していた場合、あなたはdynamic_cast議論の原因があるかもしれませんが、両方ともreinterpret_cast通常static_cast(最悪の場合)レジスタコピー(例えば整数レジスタから浮動小数点レジスタへ)につながります。(ユーザー定義の変換演算子が画像に含まれていないと仮定すると、それに付随するすべてのものを含む関数呼び出しになります)

あなたがしていることをするための安全な方法はありません。これは、厳密なエイリアシングルールに違反します。あなたがこのようなことをしたいのなら、あなたはあなたが組合を通してアクセスする場所structの何らかの形でいる必要があるでしょう。unionUInt32

最後に、すでに述べたように、その例は、アライメントの問題があるプラットフォームでは失敗します。つまり、x86では問題ありませんが、たとえばx64では問題ありません。

于 2011-06-29T15:25:22.010 に答える
0

構造体に int と short が含まれているとおっしゃっているので、この共用体が POD であると仮定して、足を踏み出して答えます。もしそうなら、9.5/1 の恩恵を受けます:

共用体の使用を簡素化するために、1 つの特別な保証が行われます。POD 共用体に、共通の初期シーケンス (9.2) を共有する複数の POD 構造体が含まれている場合、およびこの POD 共用体型のオブジェクトに POD-構造体、任意の POD 構造体メンバーの共通の初期シーケンスを検査することが許可されています

したがって、構造が次のようになっていると仮定します。

struct Foo1 { UInt32 a; other stuff; };
struct Foo2 { UInt32 b; other stuff; };
...
struct Foo15 { UInt32 o; other stuff; };
struct Bar { UInt16 p; other stuff; };

// some kind of packing pragma
struct Baz {
    char is_it_Foo;
    char something_else;
    union {
        Foo1 f1;
        Foo2 f2;
        ...
        Foo15 f15;
        Bar b;
    } u; 
};

次に、これを行うことができます:

Baz *baz = whatever;
if (baz->is_it_Foo) {
    UInt32 n = baz->u.f1.a;
}

共用体のメンバーが POD でない場合reinterpret_cast、構造体の最初のデータ メンバーが構造体の先頭からのオフセット 0 にあるという保証がなくなるため、とにかく壊れています。

于 2011-06-29T23:41:06.690 に答える
0

構造体自体ではなく、構造体へのポインターを使用していることを忘れていましたが、構造体の特定のフィールドに対してポインター演算を使用する必要はありません。コンパイラーと生成されたコードは、ポインター演算を使用しても速くならず、コードが不必要に複雑になります。

struct AnyInfoStruct {
   char Name[65]; 
   char Address[65]; 
   short Whatever; 
   uint Years;
   union AExtraData { 
      int A; 
      char B; 
      double C; 
   } ExtraData
}; 

// recieves generic pointer, hidding struct fields:
void showMsg(void* AnyPtr)
{
  AnyInfoStruct* MyAnyInfo = &(static_cast<*AnyPtr>);
  cout << "Years: " << MyAnyInfo->Years << "\n";

  cout << "ExtraData.A: " << MyAnyInfo->ExtraData.A << "\n";
}

void main()
{
  AnyInfoStruct* MyAnyInfo; 

  // hide struct into a ptr
  void* AnyPtr = AnyInfoStruct;

  showMsg(MyAnyInfo);
}

乾杯。

UPDATE1: 例に「ユニオン」を追加しました。

于 2011-06-29T16:00:53.443 に答える