56

次のようなクラスがある場合

   class Example_Class 
   {
       private:
         int x; 
         int y; 
       public: 
         Example_Class() 
         { 
             x = 8;
             y = 9;
         }
       ~Example_Class() 
       { } 
   };

そして、次のような構造体

struct
{
   int x;
   int y;
} example_struct;

の記憶にある構造と 同様のexample_structものです。Example_Class

たとえば、次のようにすると

struct example_struct foo_struct;
Example_Class foo_class = Example_Class();

memcpy(&foo_struct, &foo_class, sizeof(foo_struct));

と(つまり、foo_class の x、y 値foo_struct.x = 8foo_struct.y = 9同じ値) ?

私が尋ねる理由は、オブジェクトを C コードと共有している C++ ライブラリ (変更したくない) があり、構造体を使用して C++ ライブラリからのオブジェクトを表現したいからです。私はオブジェクトの属性にのみ興味があります。

理想的な状況は、C と C++ コードの間の共通構造を Example_class でラップすることですが、使用中の C++ ライブラリを変更するのは簡単ではありません。

4

8 に答える 8

75

C++ 標準は、C++ がPOD (「プレーン オールド データ」)であるという基準に適合する場合、CとC++ (または-- 同じもの)のメモリ レイアウトが同一であることを保証します。では、POD とは何を意味するのでしょうか。structclassstructclassstruct

次の場合、クラスまたは構造体は POD です。

  • すべてのデータ メンバーはパブリックであり、それ自体が POD または基本型 (ただし、参照型またはメンバーへのポインター型ではない)、またはそのような配列です。
  • ユーザー定義のコンストラクタ、代入演算子、またはデストラクタはありません
  • 仮想機能はありません
  • 基本クラスはありません

許可されている唯一の「C++イズム」は、非仮想メンバー関数、静的メンバー、およびメンバー関数です。

クラスにはコンストラクタとデストラクタの両方があるため、正式には POD 型ではなく、保証はありません。(ただし、他の人が述べたように、実際には、仮想関数がない限り、2 つのレイアウトは、試したどのコンパイラでも同じである可能性があります)。

詳細については、 C++ FAQ Liteのセクション [26.7] を参照してください。

于 2009-01-08T05:30:13.643 に答える
10

example_struct のメモリ内の構造体は、Example_Class 内の構造体と類似していますか?

動作は保証されておらず、コンパイラに依存します。

そうは言っても、Example_Class に仮想メソッドが含まれていない (そして基本クラスから継承されていない) 場合、答えは「はい、私のマシンでは」です。

于 2009-01-08T01:02:35.180 に答える
7

あなたが説明した場合、答えは「おそらくはい」です。ただし、クラスに仮想関数 (基本クラスから継承できる仮想デストラクタを含む) がある場合、または多重継承を使用する場合、クラスのレイアウトは異なる場合があります。

于 2009-01-08T01:02:45.990 に答える
3

他の人が言ったことに追加するには(例:コンパイラ固有、仮想関数がない限り機能する可能性があります):

これを行う場合は、sizeof(Example_class) == sizeof(example_struct) という静的アサート (コンパイル時チェック) を強くお勧めします。BOOST_STATIC_ASSERT、または同等のコンパイラ固有またはカスタム構造を参照してください。これは、誰か (またはコンパイラの変更などの何か) がクラスを変更して一致を無効にした場合の防御の第一線です。追加のチェックが必要な場合は、メンバーへのオフセットが同じであることを実行時にチェックすることもできます。これにより、(静的サイズのアサートと共に) 正確性が保証されます。

于 2009-01-08T01:49:25.350 に答える
0

C++ のクラスと構造体は同等ですが、構造体のすべてのメンバーがデフォルトでパブリックです (クラス メンバーはデフォルトでプライベートです)。これにより、C++ コンパイラでのレガシー C コードのコンパイルが期待どおりに機能することが保証されます。

構造体ですべての高度な C++ 機能を使用することを妨げるものは何もありません。

struct ReallyAClass
{
    ReallyAClass();
    virtual !ReallAClass();

    /// etc etc etc
};
于 2009-01-08T01:52:40.507 に答える
0

データを C に渡したいときに、クラスのメンバーを構造体に明示的に代入しないのはなぜですか? そうすれば、コードがどこでも機能することがわかります。

于 2009-01-08T05:43:58.590 に答える
-2

おそらく、パブリックまたはプライベートのいずれかで、構造体からクラスを派生させるだけです。それをキャストすると、C++ コードで正しく解決されます。

于 2009-01-08T06:39:00.587 に答える