(上記で投稿したものは、実際にはいくつかのヘッダーファイルからのフラグメントであると思います。)
このようなことは通常、プログラム内のさまざまなソースファイルが、クラスのパッキングや配置設定など、さまざまなメモリレイアウト関連の設定でコンパイルされている場合に発生します。ヘッダーファイルはこれらの異なる変換ユニットに含まれており、メモリレイアウト設定の不一致のために解釈が異なります。
これらの変換ユニット間でオブジェクトを渡し始めるTest
と、問題が明らかになります。1つの変換ユニットがTest
1つのメモリレイアウトでオブジェクトを作成し、次に別の変換ユニットがそれを読み取ったり、まったく異なるメモリレイアウトを想定してオブジェクトに書き込んだりします。あなたの場合、各翻訳単位で異なって解釈されるのはインライン関数です。
メンバー関数を非インライン関数として定義すると、それらは、それらが定義されているソースファイルに固有のクラスメモリレイアウトを想定します。これにより、問題が一掃され、「機能」するようになります(アクセス機能が1つのメモリレイアウトに関連付けられているため)が、それでもなお良い状況ではありません。それでも、将来的には同様の性質のさまざまな問題が発生する可能性があります。
プログラム内のすべてのソースファイルが、まったく同じクラスのメモリレイアウト設定でコンパイルされていることを確認してください。
PSフレッドがコメントで述べたように、翻訳ユニット間のクラスメモリレイアウトの不一致は、ソースファイルが依存するヘッダーファイルを変更した後にソースファイルを再コンパイルするのを忘れるなどの無作法なものによって引き起こされる可能性があります。
このような問題のもう1つの「人気のある」原因は、プリプロセッサディレクティブに依存するクラス定義です(つまり、#ifdef
/#endif
セグメントによって「カスタマイズ」されたクラスレイアウト)。#define
ヘッダーファイルを含むソースファイルで重要なことを忘れると、そのソースファイルのクラスのメモリレイアウトが異なる可能性があります。