Domanda

Ho ereditato una grande applicazione originariamente scritta in C (ma nel frattempo vi è stato aggiunto anche molto C++).Per ragioni storiche, l'applicazione contiene molti puntatori void.Prima di iniziare a soffocare, lasciami spiegare perché è stato fatto.

L'applicazione contiene molte strutture dati diverse, ma sono archiviate in contenitori "generici".Al giorno d'oggi utilizzerei contenitori STL basati su modelli, oppure darei a tutte le strutture dati una classe base comune, in modo che il contenitore possa memorizzare puntatori alla classe base, ma ai [buoni?] vecchi tempi del C, l'unica soluzione era quella trasforma il puntatore alla struttura in un puntatore a void.

Inoltre, c'è molto codice che funziona su questi puntatori void e utilizza costruzioni C molto strane per emulare il polimorfismo in C.

Ora sto rielaborando l'applicazione e cercando di eliminare i puntatori vuoti.Aggiungere una classe base comune a tutte le strutture dati non è così difficile (pochi giorni di lavoro), ma il problema è che il codice è pieno di costruzioni come mostrato di seguito.

Questo è un esempio di come vengono archiviati i dati:

void storeData (int datatype, void *data);    // function prototype
...
Customer *myCustomer = ...;
storeData (TYPE_CUSTOMER, myCustomer);

Questo è un esempio di come i dati vengono recuperati nuovamente:

Customer *myCustomer = (Customer *) fetchData (TYPE_CUSTOMER, key);

In realtà voglio sostituire tutti i puntatori void con alcuni puntatori intelligenti (contati dei riferimenti), ma non riesco a trovare un trucco per automatizzare (o almeno) aiutarmi a sbarazzarmi di tutti i cast da e verso void- puntatori.

Eventuali suggerimenti su come trovare, sostituire o interagire in qualsiasi modo possibile con queste conversioni?

È stato utile?

Soluzione 3

Apparentemente, non esiste un modo/trucco automatizzato per convertire o trovare tutti gli usi dei puntatori void.Dovrò utilizzare il lavoro manuale per trovare tutti i puntatori void, in combinazione con PC-Lint che genererà errori ogni volta che si verifica una conversione errata.

Caso chiuso.

Altri suggerimenti

In realtà voglio sostituire tutti i punti vuoti con un po 'di smart-pointer (conteggiato da riferimento), ma non riesco a trovare un trucco per automatizzare (o almeno) aiutarmi a sbarazzarmi di tutti i cast da e per il vuoto puntatori.

Tale refactoring automatizzato comporta molti rischi.

Altrimenti, a volte mi piace fare brutti scherzi trasformando tali funzioni void* in funzioni template.Quello:

void storeData (int datatype, void *data);

diventa:

template <class T>
void storeData (int datatype, T *data);

Inizialmente implementa il modello semplicemente racchiudendo la funzione originale (rinominata) e convertendo i tipi.Ciò potrebbe consentirti di vedere potenziali problemi, già semplicemente compilando il codice.

Probabilmente non è necessario eliminare i cast per utilizzare i puntatori condivisi.

storeData(TYPE_CUSTOMER, myCustomer1->get());

shared_ptr<Customer> myCustomer2(reinterpret_cast<Customer*>fetchData(TYPE_CUSTOMER, "???");

Naturalmente, ciò presuppone che non ci si aspetti di condividere lo stesso puntatore tra le chiamate a store/fetch.In altre parole, myCustomer1 e myCustomer2 non condividono lo stesso puntatore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top