Я наследовал большое приложение, которое было первоначально записано в C (но тем временем много C++ было также добавлено к нему). Из-за исторических причин приложение содержит много указателей пустоты. Прежде чем Вы начнете дросселировать, позвольте мне объяснить, почему это было сделано.
Приложение содержит много различных структур данных, но они хранятся в 'универсальных' контейнерах. В наше время я использовал бы, обработал контейнеры STL по шаблону для него, или я дам всем структурам данных общий базовый класс, так, чтобы контейнер мог сохранить указатели на базовый класс, но в [хороший?] старые дни C, единственное решение состояло в том, чтобы бросить указатель структуры на указатель пустоты.
Кроме того, существует много кода, который работает над этими указателями пустоты и использует очень странные конструкции C для эмуляции полиморфизма в C.
Я теперь переделываю приложение и пытаюсь избавиться от указателей пустоты. Добавление общего базового класса ко всем структурам данных не состоит в том, что трудно (несколько дней работы), но проблема состоит в том, что код полон конструкций как показанный ниже.
Это - пример того, как данные хранятся:
void storeData (int datatype, void *data); // function prototype
...
Customer *myCustomer = ...;
storeData (TYPE_CUSTOMER, myCustomer);
Это - пример того, как данные выбираются снова:
Customer *myCustomer = (Customer *) fetchData (TYPE_CUSTOMER, key);
Я на самом деле хочу заменить все указатели пустоты некоторым (считаемым на ссылку) интеллектуальным указателем, но я не могу найти, что прием для автоматизации (или по крайней мере) помогает мне избавиться от всех бросков к и от указателей пустоты.
Какие-либо подсказки относительно того, как найти, замените или взаимодействуйте каким-либо возможным способом с этими преобразованиями?
По-видимому, не существует автоматического способа / уловки для преобразования или поиска всех вариантов использования указателей на пустоту. Мне придется использовать ручной труд, чтобы найти все указатели void, в сочетании с PC-Lint, который будет выдавать ошибки всякий раз, когда происходит неправильное преобразование.
Дело закрыто.
Я действительно хочу заменить все пустые указатели с некоторым умным указателем (подсчитано ссылок), но я не могу найти трюк для автоматизации (или хотя бы) помощи мне, чтобы избавиться от всех слепков и из пустых указателей.
Такой автоматический рефакторинг несет в себе множество рисков.
В остальном, иногда мне нравится подшучивать, превращая такие функции void * в функции шаблона. Это:
void storeData (int datatype, void *data);
становится:
template <class T>
void storeData (int datatype, T *data);
Сначала реализуйте шаблон, просто обернув исходную (переименованную) функцию и преобразовав типы. Это может позволить вам увидеть потенциальные проблемы - уже просто путем компиляции кода.
Возможно, вам не нужно избавляться от приведений, чтобы использовать общие указатели.
storeData(TYPE_CUSTOMER, myCustomer1->get());
shared_ptr<Customer> myCustomer2(reinterpret_cast<Customer*>fetchData(TYPE_CUSTOMER, "???");
Конечно, это предполагает, что вы не ожидаете использования одного и того же указателя для вызовов store / fetch. Другими словами, myCustomer1 и myCustomer2 не используют один и тот же указатель.