私のアプリケーションには、Car、Bicycle、Person など、さまざまなデータ型がたくさんあります (実際には他のデータ型ですが、これは単なる例です)。
私のアプリケーションにはかなりの「ジェネリック」コードもあり、アプリケーションはもともと C で書かれていたため、車、自転車、人などへのポインタは、ID とともにこれらのジェネリック モジュールへの void ポインタとして渡されることがよくあります。次のようなタイプの
Car myCar;
ShowNiceDialog ((void *)&myCar, DATATYPE_CAR);
「ShowNiceDialog」メソッドはメタ情報 (DATATYPE_CAR をインターフェイスにマップして Car から実際のデータを取得する関数) を使用して、指定されたデータ型に基づいて車の情報を取得するようになりました。そうすれば、新しいデータ型ごとに毎回ではなく、ジェネリック ロジックを 1 回だけ記述する必要があります。
もちろん、C++ では、次のように共通のルート クラスを使用することで、これをはるかに簡単にすることができます。
class RootClass
{
public:
string getName() const = 0;
};
class Car : public RootClass
{
...
};
void ShowNiceDialog (RootClass *root);
問題は、場合によっては、データ型をクラスに格納したくないが、メモリを節約するためにまったく異なる形式で格納したいことです。場合によっては、アプリケーションで管理する必要がある数億のインスタンスがあり、すべてのインスタンスに対して完全なクラスを作成したくない場合があります。2 つの特性を持つデータ型があるとします。
- 数量 (double、8 バイト)
- ブール値 (1 バイト)
この情報を格納するのに 9 バイトしか必要ありませんが、クラスに入れると (パディングのため) 少なくとも 16 バイトが必要になり、v-pointer を使用すると 24 バイトも必要になる可能性があります。数億のインスタンスの場合、すべてのバイトがカウントされます (アプリケーションの 64 ビット バリアントがあり、場合によっては 6 GB のメモリが必要です)。
void-pointer アプローチには、void-pointer でほとんど何でもエンコードし、そこからの情報が必要な場合にそれを使用する方法を決定できるという利点があります (実際のポインターとして、インデックスとして使用するなど)。型安全性のコスト。
汎用ロジックはアプリケーションのかなりの部分を形成するため、テンプレート化されたソリューションは役に立ちません。これらすべてをテンプレート化することは望ましくありません。さらに、データ モデルは実行時に拡張できます。これは、テンプレートが役に立たないことも意味します。
void-pointer よりもこれを処理するためのより良い (そして型安全な) 方法はありますか? これに関するフレームワーク、ホワイトペーパー、研究資料への参照はありますか?