0

さて、メモリブロックを共有するプロセスがいくつかあります。これらのメモリ ブロックは、bar 型のオブジェクトをメンバーとして持つデータ構造です。

// in header bar.hpp

struct foo {
  double var1;
  double var2;

  foo() 
    : var1(0.0),
      var2(0.0)
  {}

};


struct bar {

  foo fooArray[5];

  double & var1;
  double & var2;

  bar()
    : fooArray(),
      var1(fooArray[0].var1),
      var2(fooArray[0].var2)
  {}

  bar(const bar& a)
    : fooArray(),
      var1(fooArray[0].var1),
      var2(fooArray[0].var2)
  {*this = a;}

  void operator=(const bar& a) {
    for(int i=0; i<5; ++i) fooArray[i] = a.fooArray[i];
  }

};

そして、共有メモリのデータ構造:

struct shmType {

  bar data;

};

bar::var1 と bar::var2 を参照する理由は、元の構造体 bar にはこれらの var1 と var2 が単純なデータ メンバーとしてあり、fooArray がなかったためです。これを拡張して、これらのデータを配列に入れることにしました。bar 構造体の実際のコードと範囲は非常に大きいので、特に var1 という名前が構造体バーに固有のものではありません (そのため、検索/置換を行うことはできません)。

参照を行う際の問題は、これらの参照を表すために bar クラスに格納されている内部ポインターがプロセス間で互換性がないことです。あるプロセスで共有メモリに bar オブジェクトを作成し、別のプロセスでそのオブジェクトの bar::var1 参照にアクセスしようとすると、セグ フォールトが発生します。(これは予想されることです)

私の質問は: bar::var1/var2 が実際にはローカル サブ構造体の単なるエイリアスであることをコンパイラに認識させる方法はあるので、参照を「コンパイルする」だけですか? bar::var1/2 の初期化子は、各オブジェクトがどのようにインスタンス化されても変わらないので、可能だと思いますが、その方法はわかりません。

4

1 に答える 1

0

unionコンパイラによっては、匿名と一緒に匿名を使用できる場合がありますstructこれは標準の C++ではないことに注意してください。実際にはコンパイラに依存するため (GCC では許可されていますが、他のコンパイラについてはわかりません)、移植可能なコードを記述したい場合は非常に壊れやすい可能性があります。

struct Foo {
  int x, y;
};

struct Bar {
  union {
    Foo fooArray[5];
    struct {
      int x;
      int y;
    }; // warning: ISO C++ prohibits anonymous structs [-pedantic]
  };
};

それでも、私は自分のコメントを支持します。最善の解決策は、おそらく全体をリファクタリングし、パブリック変数の代わりにアクセサーを使用することです。これにより、将来的に多くの頭痛が解消されます。

于 2013-07-30T19:48:53.287 に答える