2012-01-09 9 views
6

私はクエリを持っています。私は、列名とネイティブデータ型を含むフラットファイル(たとえば、file1、file2など)のセットを持っています。 (どのように値が格納され、C++で読み取ることができるかは小文字です) 例:フラットファイルfile1は、 col1_name = id、col1_type = integer、col2_name = Name、col2_type = stringなどのデータを持つことができます。実行時にクラスを作成するC++、

したがって、各フラットファイルに対して、メンバ変数名は列名と同じ名前で、データ型はintのようなC++のネイティブデータ型になります(つまり、フラットファイル= 1のデータ構造)。 、フロート、ストリングなどのフラットファイルの列の種類に応じて。例えば上から :私のフラットファイル1が宣言

class file1{ 
    int id; 
    string Name; 
}; 

の下に私を与える必要があり、私は一度作成されたバイナリは、フラットファイルを読み込み、ファイルに基づいてデータ構造を作成するC++、(でコードを書くことができる方法はありますクラス名はフラットファイル名と同じになります)。これらのフラットファイルを使用して作成されたすべてのクラスは、getterおよびsetterメンバ関数の共通の機能を持ちます。

先ほど同様のことをしたことがありましたら、教えてください。

+2

申し訳ございません。代わりにバリアントデータ型に文字列(プロパティ名)のマップのようなものを使用する必要があります。 – Jon

+1

実行時にC++でクラス定義を作成することはできません。スクリプト言語やC++を使用して、そのようなフラットファイルを読み込み、ソースファイルを吐き出して後でコンパイルすることができます。 –

+0

私は決して['boost :: any'](http://www.boost.org/doc/libs/1_48_0/doc/html/any.html)を使ったことはありません。それは@ rockyの問題を解決するのに役立つでしょうか? –

答えて

5

C++クラスは純粋なコンパイル時の概念であり、実行時に意味を持たないため、作成できません。ただし、アクセサー関数で必要に応じて解析するだけで

std::vector<std::string> fields; 

とすることができます。

+1

'boost :: any'は' std :: string'よりも優れているかもしれません。 –

8

いいえ、直接ではありません。 C++はコンパイルされた言語です。すべてのクラスのコードは、コンパイラによって作成されます。

2段階のプロセスが必要です。まず、これらのファイルを読み込み、.cppファイルに変換するプログラムを作成します。次に、それらの.cppファイルをコンパイラに渡します。

+0

これは実行時になりません –

+1

@セス:それで私の答えの最初の言葉は "いいえ"です。しかし、あなたは_could_このコードをDLLにコンパイルし、それを動的にロードできます。それは役に立ちますか?この質問から私は分かりません。 – MSalters

+0

信じられないほどのアイデアをコンパイルし、dll、いいものを読み込んでいます。これは私の現在のプロジェクトで興味深い実験的な解決策になる可能性があります –

7

いいえ、簡単にはありません(なぜそうでないのかはtheotheranswersを参照してください)。

私はこの種の問題の代わりにPythonを見ることをお勧めします。 Python's type systemとその使用法を組み合わせると、try/exceptは、データを解析するのがより簡単になります。

あなたは本当にC++を使用する必要がある場合、あなたはQVariantクラスと組み合わせるQtQObjectクラスのdynamic properties機能を使用して、解決策を見つけるかもしれません。これがあなたの望むことをするでしょうが、私はという警告を追加します。これは重量が重くなりすぎて作業が複雑になる可能性があります。

+0

@ downvoter、なぜこれが役に立たないのかを説明するケア?それは、あなたが以前に何か類似したことをやったことがあるのか​​、それとも何か考えがあるのなら、私に知らせてくれます。 –

+2

私を打ち負かす。 +1、これは私の意見では有効な点です。 –

+0

私もあなたと一緒にいます - (+1) –

4

いいえ、わかりますが、複数の列の名前を格納できる必要があります。あなたができることは、メンバ変数mapまたはunordered_mapです。これは、文字列(列の名前)でインデックスを作成し、何らかのデータ(列オブジェクトなど)を戻すことができます。あなたは

obj.Columns["Name"] 
0

を行うことができますこうすることで、私はこれまでデザインパターンがありますわからないんだけど、可能なタイプ名のリストが有限であり、コンパイル時に知られているならば、あなたは内のすべてのこれらのクラスを宣言することはできませんあなたのプログラムを実行する前に、その後、ファイル内のデータに基づいてインスタンス化するだけですか?

+0

すべて、私の質問に返信してくれてありがとうとありがとう。また、私の主な関心事は、単一のバイナリを実装して別のクライアントに出荷することです。クライアントによって提供されるフラットファイル構造は異なるため、このバイナリは、飛行中にデータ構造を処理できるジェネリックでなければなりません。もちろん、バイナリの主な機能はすべてのクライアントに似ていますが、クライアントが提供するさまざまなデータに対応する必要があることを除けば、このすべてが混乱します。私は私の要点を明確にしたいと考えています。私はこれがメタプログラミングやC++でのリフレクションを使って可能かもしれないと考えました。しかし、私はそれらの概念に新しく静かです。 –

+0

私は、これらのテキストファイルを解析するための入力として見てください。個人的には、データを格納するために共用体を使用します。もちろん、テキストファイルで何を期待して構造を考えていなければ、すべての異なるデータを含めることができます。それ以外の場合は動作しません。 –

0

実際には、実行時に正確な性質が変わるフィールドが必要です。

Boost.Anyを含むいくつかのアプローチがありますが、C++タイプのシステムの静的な性質のため、実際には2つしか推奨されておらず、必要なすべての可能なデータタイプのアイデアを事前に持っている必要があります。

第1のアプローチは、典型的である:

  • Objectベース型
  • IntStringDate何らかの派生型

及び多型の使用。

2番目のブーストマジックのビットは、boost::variant<int, std::string, date>です。

「バリアント」の部分がカバーされたら、異なる可能性のあるタイプを区別するために訪問を実装する必要があります。従来のオブジェクト指向アプローチの典型的な訪問者、または単純にboost::static_visitor<>およびboost::apply_visitorの組み合わせ。

これはかなり簡単です。

関連する問題