2

私は小さな問題を抱えています:

class A {
     public:
     enum _type {TYPE1=0,TYPE2,TYPE3} type;
     union U{
         struct _type1 {
             //somme data
         } type1;

         struct _type2 {
            //some other data
            std::vector<int> v;
         } type2;

         struct _type3 {
            // some other data
         } type3;

         U() { //constuctor
            switch(type){ // access to A::type => not accept at compile time
               case TYPE1 : /*init type1*/ break;
               case TYPE2 : /* init type2 */; new(&v) std::vector<int>; break;
               case TYPE3 : /* init type3 */ break;
               default : break;
         }

         ~U(){ //I need it to delete placement new
             switch(type)
             {
                  //same probleme
                  case TYPE2: v.~vector<int>(); break;
                  default : break;
             }
        }
     }
 };

エラー:

非静的データメンバーの無効な使用

ご覧のとおり、ユニオンコンストラクターでメインクラスのデータにアクセスする必要があります。「無制限のユニオン」(ユニオンのデータメンバーは実際にはオブジェクトです)を処理するためにこれが必要なので、他のクラスではなくユニオンを使用する必要があります。

編集:最後に、私はこの場合の解決策を見つけます:

class A {
    public:
        A(int t); // <= add U() code here
        ~A(); // <= add ~U()  code here
    union {
        //same union data
    }; //move to anonymous union
};
4

3 に答える 3

2

他の場合と同様に、 A のインスタンスをコンストラクターに渡す必要があります。共用体が A 内で宣言されているという事実は無関係です。

編集:ちなみに、あなたはちょうど再発明boost::variantしています。

于 2012-12-26T18:43:54.550 に答える
2

オブジェクト内に物理的に「内部結合」オブジェクトはありませんA。あなたがしたことは、別の型の中で型を宣言することだけです。Aこれは名前付けとアクセス権に影響しますが、 と の間に他の関係は作成されませんU

Uタイプのオブジェクトのメンバーとしてタイプのオブジェクトを物理的に持ちたい場合は、クラスA でタイプのメンバーを宣言する必要があります。これにより、オブジェクトとその type のメンバーとの間に物理的な関係が作成されます。C++ 言語は、データ メンバーから所有者のアドレスを特定するための標準的な手段を提供していませんが、準合法的なハックによって実現できます。UAAU

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

class A {
public:
  union U {
    ...
  };
  ...
  U u;
};

実行することで、Aメソッド内から全体にアクセスできるようになりますU

A *pa = static_cast<A *>((void *) ((char *) this - offsetof(A, u)));

これは明らかに、ハードコーディングされuたクラス メンバーの名前に依存する、かなり洗練されていないハックです。それでも、技術的な可能性はあります。

または、単にエンベロープAオブジェクトへのポインタ/参照をオブジェクトに渡し、Uそのポインタ/参照を介してアクセスを実行することもできます。


ただし、あなたの例に固有の別の性質の問題があります。メンバー サブオブジェクトのコンストラクタデストラクタから所有者クラスにアクセスしようとしているようです。メンバー サブオブジェクトは、所有者オブジェクトのに構築されます。また、メンバー サブオブジェクトは、所有者オブジェクトの後に破棄されます。これは、s コンストラクターとデストラクタから見えるものUは、まだ構築されていないか、タイプ のオブジェクトが既に破壊されていることを意味しますA。この場合、所有者オブジェクトの他のメンバー (特に重要なもの) にアクセスしようとするのは得策ではありません。

于 2012-12-26T19:05:49.317 に答える
0

コンストラクタとデストラクタが間違った場所にあります。それらをユニオンから に移動しますclass A

于 2012-12-26T19:02:57.003 に答える