従来の C++ DB アプリケーションがありますが、ここでは単純化しすぎます。10 を超える非常に幅の広い DB テーブルは、部分的に類似した種類のデータを表しているため、列が重複しています。スキーマは数か月ごとに少しだけ変更されますが、スキーマへのインターフェイスは動的であり、table_name.column_name が検索され、ID で表されます。メモリ内のデータを処理する場合、すべてがリストにあり、各フィールドには ID が関連付けられています。
これはうまく機能しますが、データのアドレス指定は面倒です。文字列 ( ) に基づく ID のルックアップ関数がありget_ID( type_A1, "title" )
、特定の型を処理するコードがある場合、同僚は ID を文字どおりに記述する傾向があります。文字列に対応する記号名を生成して、コンパイル時にその多くを検索できるようにしたいと考えています。私の素朴な考えは次のようになりました:
struct ANY {
virtual const int
title, aaa, bbb, ccc, ddd; // ...
}
struct A1 : ANY {
const int
title=17, aaa=29, bbb=5, ddd=27;
}
struct B1 : ANY {
const int
title=71, aaa=92, ccc=45;
}
そして、使用法は、直接A1::bbb
、またはB1::aaa
どのタイプを扱っているかがわかっている場合、または次のいずれかになります。
const ANY& any = determine_type();
int title_id = any.title;
悲しいかな、C++ ではこれが許可されていません。メソッドのみが仮想化できます。:-( 解決策の 1 つは、それらをメソッドでラップすることです。
struct ANY {
virtual int get_title() const = 0;
virtual int get_aaa() const = 0;
}
struct B1 : ANY {
const int
title=71, aaa=92, ccc=45;
int get_title() const { return title; };
int get_aaa() const { return aaa; };
}
何千もの const の場合、このアプローチは非常に間違っているように感じます! 別の解決策は、間接的な名前とルックアップ関数を介して動的部分を実行することです。
enum names { title_name, aaa_name, bbb_name, ccc_name };
struct ANY {
virtual int get( names ) const = 0;
}
struct B1 : ANY {
const int
title=71, aaa=92, ccc=45;
static const int[] my_consts = { title, aaa, -1, ccc }; // pseudo code
int get( names n ) const { return my_consts[n]; };
}
これは、すべての識別子を 2 つのバリアントで持つことを意味します – 醜い! クリーンで直感的でスペース効率の良いソリューションを持っている人はいますか?