2

私はコードを書いていて、今まで次のような構造を使用していました。

struct s{
  enum Types { zero = 0, one, two };
  unsigned int type;
  void* data;
} 

さまざまなクラスのデータを格納するための一般的な構造が必要であり、それをstd :: vectorで使用したかったので、テンプレートを使用できません。より良いオプションは何ですか:ユニオンまたはvoidポインター?

ボイドポインタは必要なだけのスペースを割り当てますが、c ++は何らかの理由で強い型付き言語であり、これらのデータを使用する必要がある場所にキャストすることは、c++コードを設計する方法ではありません。私が読んだように、代替手段がない限り、voidポインタは使用されるべきではありません。

その代替案は組合である可能性があります。これらはC++に付属しており、voidポインターと非常によく似て、すべてのメンバーに同じメモリスペースを使用します。ただし、価格が高くなります。割り当てられたスペースは、ユニオンで最大の要素のサイズであり、私の場合、サイズ間の違いは大きくなります。

どちらの方法でも必要なことを実行できるため、これはかなり文体的で「正しい言語を使用する」問題ですが、適切に様式化されたc ++コードがその無駄なメモリを補うことができるかどうかを判断できません(最近のメモリはそれほど大きくありませんが)懸念)。

4

3 に答える 3

5

異種タイプのオブジェクトを格納するboost::anyかどうかを検討してください。boost::variant

どちらを使用するかを決定する前に、比較を見てください。

うまくいけば、正しい決定を下すのに役立ちます。std::vector<boost::any>std::vector<boost::variant>、またはその他のオブジェクトを格納するために、標準ライブラリから 1 つおよび任意のコンテナーを選択します。

于 2011-08-20T14:12:45.770 に答える
1

boost::variant

基本的にはタイプセーフなユニオンであり、この場合、ユニオンが断然最も適切な答えのようです。Avoid*を使用することもできますが、これは動的割り当てを意味しTypes enum、キャスト用の、、およびテーブルを維持する必要があります。

メモリの制約はvoid*許容できる選択になる可能性がありますが、それは「きちんとした」答えではありません。両方boost::variantと単なるプレーンunionが許容できないことが示されるまで、私はそれを選びません。

于 2011-08-20T14:16:04.707 に答える
1

クラスに同じコンテナーに配置するのに十分な共通点がある場合は、仮想デストラクタを持つ基本クラスと、型コードを取得するための仮想メンバー関数を与えることができます。より完全な共通インターフェースをクラスに提供するのに十分な共通点がないかどうかを調査することは合理的かもしれません。

それ以外の場合は、適切に型指定されたデータ メンバーを持つカスタム コンテナー クラスを提供して、そこに入れる必要があるすべての異なるクラスのインスタンスを保持することを検討してください。

于 2011-08-20T14:24:06.157 に答える