NullPointerException
s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException
. Они наиболее распространены, но другие способы перечислены на странице NullPointerException
javadoc.
Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException
, be:
public class Example {
public static void main(String[] args) {
Object obj = null;
obj.hashCode();
}
}
В первой строке внутри main
я явно устанавливаю ссылку Object
obj
равной null
. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException
, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.
(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)
Только что запустив на в значительной степени том же самом несколько месяцев назад (на десятилетнем коммерческом проекте, первоначально записанном с "C++, только C с умным struct
с" философия), я предложил бы использовать ту же стратегию, которую Вы будете использовать для употребления в пищу слона: возьмите его один укус за один раз.:-)
как можно больше, разделяет его на этапы, которые могут быть сделаны с минимальными эффектами на другие части. Создание системы фасада, как Federico Ramponi предложенный, является хорошим началом - как только все имеет фасад C++ и связывается через него, можно изменить внутренности модулей со справедливой уверенностью, что они ни на что не могут влиять вне их.
Мы уже имели в распоряжении частичную систему интерфейса C++ (из-за предыдущих меньших усилий по рефакторингу), таким образом, этот подход не был трудным в нашем случае. Как только у нас было все связывающееся как объекты C++ (который занял несколько недель, работающих над абсолютно отдельным ответвлением исходного кода и интегрирующих все изменения в основном ответвлении, поскольку они были утверждены), это было очень редко, что мы не могли скомпилировать полностью рабочую версию, прежде чем мы уехали в течение дня.
переключение еще не завершено - мы приостановились дважды для временных выпусков (мы стремимся к доработанной версии каждые несколько недель), но оно уверенно двигается, и никакой клиент не жаловался ни на какие проблемы. Наши люди QA только нашли одну проблему, которую я вспоминаю, также.:-)
Что относительно:
, Почему "перевод в обязательный C++"? Можно обернуть код C без боли преобразования его в огромные классы и так далее.
Я записал бы классы C++ по интерфейсу C. Касание кода C уменьшит шанс того, чтобы портить и значительно ускорит процесс.
, Как только у Вас есть свой интерфейс C++; тогда это - тривиальная задача copy+pasting код в Ваши классы. Как Вы упомянули - во время этого шага, жизненно важно сделать поблочное тестирование.
Ваш список смотрит хорошо кроме, я предложил бы рассмотреть набор тестов сначала и попытаться получить это максимально трудное прежде, чем сделать любое кодирование.
Давайте бросим другую глупую идею:
Вероятно, две вещи рассмотреть, кроме того, как Вы хотите запуститься, включены, что Вы хотите к [1 110] фокус , и где Вы хотите к [1 111] остановка .
Вы заявляете, что существует большая маслобойка кода, это может быть ключом к фокус Ваши усилия. Я предлагаю, чтобы Вы выбрали части своего кода, где большое обслуживание необходимо, зрелые/стабильные части по-видимому рабочие достаточно хорошо, таким образом, лучше оставить их, как они, кроме, вероятно, для некоторого оформления витрины с фасадами и т.д.
, Где Вы хотите остановиться, зависит от того, что причина для желания преобразовать в C++. Это может едва быть целью сам по себе. Если это происходит из-за некоторой сторонней зависимости, сфокусируйте свои усилия на интерфейсе к тому компоненту.
программное обеспечение, я продолжаю работать, является огромной, старой кодовой базой, которая была 'преобразована' от C до C++ несколько лет назад теперь. Я думаю, что это было, потому что GUI был преобразован в QT Даже сейчас, это все еще главным образом похоже на программу C с классами. Повреждение зависимостей, вызванных общедоступными элементами данных и рефакторинг огромных классов с процедурными методами монстра в меньшие методы и классов никогда, действительно не взлетали, я думаю по следующим причинам:
нбар. Я предполагаю, что Вы знаете "Работу эффективно с Унаследованным кодом" книга?
Если у Вас есть маленький или академический проект (скажите, меньше чем 10 000 строк), перезапись является, вероятно, Вашим наилучшим вариантом. Можно учесть его однако, Вы хотите, и не потребуется слишком большого количества времени.
, Если бы у Вас есть реальное приложение, я предложил бы заставить его компилировать как C++ (который обычно означает, прежде всего, ремонтировать прототипов функции и т.п.), затем работайте над обертыванием OO и рефакторингом. Конечно, я не подписываюсь на философию, которые кодируют потребности быть OO, структурированным, чтобы быть приемлемым кодом C++. Я сделал бы преобразование части частью, переписав и осуществив рефакторинг, поскольку Вам нужно к (для функциональности или для слияния поблочного тестирования).
Вот то, что я сделал бы:
Над вашим приложением работает много людей, и их нужно не нарушать. Если вы серьезно относитесь к крупномасштабному преобразованию в объектно-ориентированный стиль, какой вам нужны инструменты массового преобразования для автоматизации работы.
Основная идея состоит в том, чтобы обозначить группы данных как классы, а затем получить инструмент для рефакторинга кода, чтобы переместить эти данные в классы, переместить функции только с этими данными в эти классы, и пересмотреть все обращения к этим данным для вызова классов.
Вы можете выполнить автоматический предварительный анализ, чтобы сформировать статистические кластеры, чтобы получить некоторые идеи, но вам все равно понадобится инженер, знающий о приложениях, чтобы решить, что элементы данных должны быть сгруппированы.
Инструмент, способный выполнить эту задачу, - это наша DMS Software Reengineering. Инструментарий . DMS имеет сильные синтаксические анализаторы C для чтения вашего кода, захватывает код C. как абстрактные синтаксические деревья компилятора (и в отличие от обычного компилятора) может вычислить анализ потока для всего вашего 300 000 SLOC. У DMS есть интерфейс C ++, который можно использовать как «бэкэнд»; один пишет преобразования, которые отображают синтаксис C на синтаксис C ++.
Основная задача реинжиниринга C ++ в большой системе авионики дает некоторое представление о том, что такое использование DMS для такого рода деятельности. См. Технические документы на www.semdesigns.com/Products/DMS/DMSToolkit.html, конкретно Реинжиниринг моделей компонентов C ++ посредством автоматического преобразования программ
Этот процесс не для слабонервных. Но чем кто-либо что учитывает ручной рефакторинг большого приложения уже не боится тяжелой работы.
Да, я связан с компанией, являюсь ее главным архитектором.
GCC в настоящее время находится на стадии перехода на C ++ с C. Очевидно, они начали с перемещения всего в общее подмножество C и C ++. По мере того, как они это сделали, они добавили предупреждения в GCC для всего, что они нашли, в разделе -Wc ++ - compat
. Это должно помочь вам в первой части вашего путешествия.
Что касается последних частей, когда у вас действительно есть все, компилируемое с помощью компилятора C ++, я бы сосредоточился на замене вещей, имеющих идиоматические аналоги на C ++. Например, если вы используете списки, карты, наборы, битовые векторы, хэш-таблицы и т. Д., Которые определены с помощью макросов C, вы, вероятно, многого добьетесь, перенеся их на C ++. Точно так же с OO вы, вероятно, найдете преимущества там, где вы уже используете идиому C OO (например, наследование структур), и где C ++ обеспечит большую ясность и лучшую проверку типов в вашем коде.
Вы упомянули, что ваш инструмент является компилятором, и что: «На самом деле, сопоставление с образцом, а не только сопоставление типов, при многократной отправке было бы даже лучше».
Возможно, вы захотите взгляните на maketea . Он обеспечивает сопоставление с образцом для AST, а также определение AST из абстрактной грамматики, посетителей, преобразователей и т. Д.