2012-01-09 21 views
6

Ho una query, ho set di file flat (ad esempio file1, file2 ecc.) Contenenti nomi di colonne e tipi di dati nativi. (come i valori sono memorizzati e possono essere letti in C++ è elementare) es. flat file file1 può avere dati come col1_name = id, col1_type = intero, col2_name = Nome, col2_type = stringa e così via.C++, creazione di classi in runtime

Quindi per ogni file flat ho bisogno di creare una struttura dati C++ (cioè 1 file flat = 1 struttura dati) dove il nome della variabile membro è lo stesso nome della colonna e il suo tipo di dati sarà di tipo nativo C++ come int , float, stringa, ecc. in base al tipo di colonna nel file flat. dall'alto ad esempio: il mio file flat 1 mi dovrebbe dare seguito dichiarazione

class file1{ 
    int id; 
    string Name; 
}; 

C'è un modo per scrivere codice in C++, dove binario una volta creato leggerà il file flat e creare la struttura di dati in base al file (il nome della classe sarà uguale al nome file flat). Tutte le classi create utilizzando questi file flat avranno funzionalità comuni delle funzioni dei membri getter e setter.

Fammi sapere se hai fatto qualcosa di simile prima o hai qualche idea per questo.

+2

Non possibile, mi spiace. Dovrai invece utilizzare qualcosa come una mappa di stringhe (nomi di proprietà) a un tipo di dati variante. – Jon

+1

Non è possibile creare definizioni di classi in runtime in C++, è possibile utilizzare un linguaggio di scripting o anche C++ per leggere tali file flat e sputare i file sorgente e compilarli in seguito. –

+0

Non ho mai usato ['boost :: any'] (http://www.boost.org/doc/libs/1_48_0/doc/html/any.html). Questo aiuterà a risolvere il problema di @ rocky? –

risposta

5

Le classi C++ sono puri concetti in fase di compilazione e non hanno significato in fase di esecuzione, pertanto non possono essere create. Tuttavia, si può semplicemente andare con

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

e analizzare se necessario nelle funzioni di accesso.

+1

'boost :: any' potrebbe essere migliore di' std :: string'. –

8

No, non direttamente. C++ è un linguaggio compilato. Il codice per ogni classe è creato dal compilatore.

Avresti bisogno di un processo in due fasi. Per prima cosa, scrivi un programma che legge quei file e li traduce in un file .cpp. Secondo, passa quei file .cpp a un compilatore.

+0

Questo non sarebbe in fase di esecuzione –

+1

@Seth: Ecco perché la prima parola della mia risposta è "No". Tuttavia, è possibile compilare questo codice in una DLL e caricarlo in modo dinamico. È utile? Non posso dire da questa domanda. – MSalters

+0

Idea incredibile compilare e caricare una DLL, bella. Questa potrebbe essere una soluzione sperimentale interessante nel mio attuale progetto –

7

No, non facilmente (vedere theotheranswers per motivi non).

Suggerirei di dare un'occhiata a Python invece per questo tipo di problema. Python's type system combinato con il suo ethos di utilizzare try/except si presta più facilmente alla sfida di analisi dei dati.

Se davvero si deve utilizzare C++, allora si potrebbe trovare una soluzione utilizzando la funzione di dynamic propertiesQObject classe Qt s', in combinazione con la classe QVariant. Anche se questo farebbe quello che vuoi, aggiungerei un avviso che questo sta diventando pesante e potrebbe complicare eccessivamente il tuo compito.

+0

@ downvoter, Spero di spiegare perché questo non è utile? Dice abbastanza chiaramente "Fammi sapere se hai fatto qualcosa di simile prima o hai qualche idea per questo." –

+2

Mi batte. +1, poiché questo è un punto valido secondo me. –

+0

Anch'io - Sono con voi - (+1) –

4

No, ma da quello che posso dire, devi essere in grado di memorizzare i nomi di più colonne. Quello che puoi fare è avere una variabile membro map o unordered_map che puoi indicizzare con una stringa - il nome della colonna - e recuperare alcuni dati (come un oggetto colonna o qualcosa). In questo modo si può fare

obj.Columns["Name"] 
0

Non sono sicuro che ci sia un modello di progettazione a questo, ma se la vostra lista di possibili nomi di tipo è finito, e noto al momento della compilazione, non si può dichiarare tutte le classi in il tuo programma prima dell'esecuzione, e quindi basta istanziarli in base ai dati nei file?

+0

Tutto, grazie per aver risposto alla mia domanda e per avermi aiutato. Inoltre, la mia principale preoccupazione è implementare il singolo binario e spedirlo a diversi client.La struttura di file piatta fornita dai client sarà diversa, quindi questo binario dovrebbe essere generico in grado di gestire le strutture dati al volo. Ovviamente la principale funzionalità del binario è simile a tutti i client, tranne per il bisogno di soddisfare i diversi dati che il cliente ci sta dando, quindi questo è tutto un casino. Spero di chiarire il mio punto. Ho pensato che questo potesse essere possibile usando meta-programmazione o riflessioni in C++. ma sono tranquillo nuovo a questi concetti. –

+0

Penso che dovresti solo vedere quei file di testo come input da analizzare. Personalmente, userei i sindacati per archiviare i dati. Ma ovviamente, devi sapere in anticipo cosa aspettarti nei file di testo e nelle strutture di pensiero che possono contenere tutti i dati diversi, altrimenti non funzionerà. –

0

Quello che in realtà si desidera è un campo la cui natura esatta varia in fase di esecuzione.

Ci sono diversi approcci, tra cui Boost.Any, ma a causa della natura statica del sistema di tipo C++, solo 2 sono veramente raccomandati, ed entrambi richiedono di avere in anticipo un'idea di tutti i possibili tipi di dati che potrebbero essere richiesti.

Il primo approccio è tipico:

  • Object tipo base
  • Int, String, Date qualunque tipo

e l'uso del polimorfismo derivato.

Il secondo richiede un po 'di magia Boost: boost::variant<int, std::string, date>.

Una volta coperta la parte "variante", è necessario implementare la visita per distinguere tra i diversi tipi possibili. Visitatori tipici per il tradizionale approccio orientato agli oggetti o semplicemente combinazioni boost::static_visitor<> e boost::apply_visitor per l'approccio boost.

È abbastanza semplice.

Problemi correlati