前文:
私の答えはまだOKですが、次の理由から、 litbの答えは私のものよりもかなり優れていることがわかります。
- 知らなかった裏ワザを教えてくれる(litbさんの回答はたいていこのような効果があるのですが、書き留めたのはこれが初めてです)
- 質問に正確に答えます(つまり、元の構造体の部分をゼロに初期化します)
だから、私の前にlitbの答えを考えてください。実際、質問の作成者には、litb の回答を正しい回答と見なすことをお勧めします。
元の答え
真のオブジェクト (std::string) などを内部に配置すると、真のオブジェクトが memset の前に初期化され、ゼロで上書きされるため、破損します。
初期化リストの使用は g++ では機能しません (驚いています...)。代わりに、CMyStruct コンストラクター本体で初期化します。C++ フレンドリーになります。
class CMyStruct : public MY_STRUCT
{
public:
CMyStruct() { n1 = 0 ; n2 = 0 ; }
};
PS:もちろん、MY_STRUCT を制御できないと仮定しました。コントロールがあれば、コンストラクターを MY_STRUCT 内に直接追加し、継承について忘れていたでしょう。非仮想メソッドを C のような構造体に追加しても、構造体として動作させることができることに注意してください。
編集:Lou Franco のコメントの後に、不足している括弧を追加しました。ありがとう!
編集 2: g++ でコードを試しましたが、何らかの理由で初期化リストを使用しても機能しません。body コンストラクターを使用してコードを修正しました。ただし、解決策はまだ有効です。
元のコードが変更されたため、投稿を再評価してください (詳細については、変更ログを参照してください)。
編集 3 : ロブのコメントを読んだ後、彼は議論に値するポイントを持っていると思います:「同意しますが、これは新しい SDK で変更される可能性のある巨大な Win32 構造になる可能性があるため、memset は将来の証拠です。」
私は同意しません: Microsoft を知っているので、完全な下位互換性が必要なため、Microsoft が変更されることはありません。代わりに、MY_STRUCT と同じ初期レイアウトを持つ拡張 MY_STRUCT Ex構造体を作成し、最後に追加のメンバーを持ち、RegisterWindow、IIRC に使用される構造体のような「サイズ」メンバー変数で認識できます。
したがって、ロブのコメントから残っている唯一の有効なポイントは、「巨大な」構造体です。この場合、おそらく memset の方が便利ですが、MY_STRUCT を継承するのではなく、CMyStruct の変数メンバーにする必要があります。
別のハックが見られますが、構造体のアライメントの問題が発生する可能性があるため、これは壊れると思います。
編集 4: Frank Krueger のソリューションをご覧ください。移植可能であるとは約束できませんが (おそらく移植可能だと思います)、技術的な観点から見て興味深いのは、C++ で「this」ポインタの「アドレス」が基底クラスから継承されたクラスに移動する 1 つのケースを示しているからです。 .