2

数十のメンバーについて話しているので、すべてを 1 つずつコピーする変換関数を作成するようなことは本当に避けたいと思います。

4

4 に答える 4

5

最善の方法は、この冗長性をまったく持たないようにして問題を解決することです。これはDRYではありません。

適用できないと確信している簡単な解決策 (そうでなければ、既に実行している) は、2 つの型の共通の構文を基本クラスに移動し、セマンティックの違いを 2 つの派生 (おそらく空の) クラスに分離することです。

これが達成できない場合は、アダプター クラスを使用して、所有している 2 つのタイプのいずれかをカプセル化し、同じインターフェイスで両方にアクセスできます。

Obj2 o2;
Adapter<Obj2> a(o2);
a.getFirstMember();

あるオブジェクトへのポインターを別のオブジェクトへのポインターとして再解釈することも可能です。

Obj1 *p = reinterpret_cast<Obj1 *>(&obj2);

ただし、2 つのオブジェクトは実際には同じメモリ フットプリントを持つ必要があります。たとえば、両方の型でレプリケートされる任意のメンバーの可能な値については、次のことが常に true である必要があります。

memcmp(&obj1, &obj2, sizeof(Obj1)) == 0 && sizeof(obj1) == sizeof(obj2)

これを保証するのは一般的に困難であり、コンパイラが 2 つのクラスのいずれかに何かを追加すると、さらに重要な問題になる可能性があります (2 か月以内に無害なリファクタリングを行うと、この問題が簡単に発生する可能性があります)。

たとえば、仮想デストラクタを考えてみてください。1 つのクラスに (唯一の仮想メンバーとして) あり、他のクラスにない場合、その 1 つのクラスはvptr最初のメンバーとして a を持ち、もう 1 つのクラスは持たないため、両方のクラスでそのオフセットにアクセスすると、異なる結果が得られます。

于 2013-06-30T15:43:14.697 に答える
3
  1. メンバーがまったく同じで名前が異なる 2 つのデータ型を持つべきではありません。これは単なる冗長なコードです。冗長な型を取り除くようにしてください。
  2. 何らかの理由でできない場合 (信じられないほど信じられません)、単純reinterpret_castに 1 つの型を別の型にキャストします。

クラス/構造は、その構成に関して完全に同一である必要があり、仮想メンバーを持たないことに注意してください。

于 2013-06-30T15:06:53.213 に答える