如何摆脱空指针
我继承了一个最初用 C 编写的大型应用程序(但同时也添加了很多 C++)。由于历史原因,应用程序包含大量空指针。在你开始窒息之前,让我解释一下为什么这样做。
该应用程序包含许多不同的数据结构,但它们存储在“通用”容器中。如今,我会使用模板化的 STL 容器,或者我会给所有数据结构一个公共基类,以便容器可以存储指向基类的指针,但在[好?]旧的 C 时代,唯一的解决方案是将结构指针转换为 void 指针。
此外,有很多代码可以处理这些 void 指针,并使用非常奇怪的 C 结构来模拟 C 中的多态性。
我现在正在重新设计该应用程序,并尝试摆脱 void 指针。向所有数据结构添加一个公共基类并不难(几天的工作),但问题是代码充满了如下所示的结构。
这是如何存储数据的示例:
void storeData (int datatype, void *data); // function prototype
...
Customer *myCustomer = ...;
storeData (TYPE_CUSTOMER, myCustomer);
这是如何再次获取数据的示例:
Customer *myCustomer = (Customer *) fetchData (TYPE_CUSTOMER, key);
我实际上想用一些智能指针(引用计数)替换所有空指针,但我找不到技巧自动化(或至少)帮助我摆脱所有往返于空指针的强制转换。
关于如何查找、替换这些转换或以任何可能的方式与这些转换进行交互,有什么建议吗?
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 many 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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这种自动化重构存在很多风险。
否则,有时我喜欢用这样的 void* 函数来玩弄模板函数。那:
变成:
首先通过简单地包装原始(重命名)函数并转换类型来实现模板。这可能会让您发现潜在的问题 - 只需编译代码即可。
Such automated refactoring bears many risks.
Otherwise, sometimes I like to play tricks by making out of such void* functions the template functions. That:
becomes:
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.
您可能不需要摆脱强制转换即可使用共享指针。
当然,这假设您不希望在存储/获取调用之间共享相同的指针。换句话说,myCustomer1 和 myCustomer2 不共享相同的指针。
You probably don't need to get rid of the casts to use shared pointers.
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.
显然,没有自动的方法/技巧来转换或查找空指针的所有用途。我将不得不使用手工劳动来查找所有空指针,并结合 PC-Lint,只要存在不正确的转换,就会给出错误。
案件结案。
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.