开发者

How to get rid of void-pointers

I inherited a big application that was originally written in C (but in the mean time a lot of C++ was also added to it). Because of historical reasons, the application contains a lot of void-pointers. Before you start to choke, let me explain why this was done.

The application contains ma开发者_C百科ny different data structures, but they are stored in 'generic' containers. Nowadays I would use templated STL containers for it, or I would give all data structures a common base class, so that the container can store pointers to the base class, but in the [good?] old C days, the only solution was to cast the struct-pointer to a void-pointer.

Additionally, there is a lot of code that works on these void-pointers, and uses very strange C constructions to emulate polymorphism in C.

I am now reworking the application, and trying to get rid of the void-pointers. Adding a common base-class to all the data structures isn't that hard (few days of work), but the problem is that the code is full of constructions like shown below.

This is an example of how data is stored:

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

This is an example of how data is fetched again:

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

I actually want to replace all the void-pointers with some smart-pointer (reference-counted), but I can't find a trick to automate (or at least) help me to get rid of all the casts to and from void-pointers.

Any tips on how to find, replace, or interact in any possible way with these conversions?


I actually want to replace all the void-pointers with some smart-pointer (reference-counted), but I can't find a trick to automate (or at least) help me to get rid of all the casts to and from void-pointers.

Such automated refactoring bears many risks.

Otherwise, sometimes I like to play tricks by making out of such void* functions the template functions. That:

void storeData (int datatype, void *data);

becomes:

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

At first implement template by simply wrapping the original (renamed) function and converting the types. That might allow you to see potential problems - already by simply compiling the code.


You probably don't need to get rid of the casts to use shared pointers.

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

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

Of course, this assumes that you don't expect to share the same pointer across calls to store/fetch. In other words, myCustomer1 and myCustomer2 don't share the same pointer.


Apparently, there is no automated way/trick to convert or find all uses of void-pointers. I'll have to use manual labor to find all void-pointers, in combination with PC-Lint that will give errors whenever there is an incorrect conversion.

Case closed.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜