Відмінності між Java і C++

Глобальні змінні. У старі добрі часи Фортрану, коли справжні чоловіки писали на Асемблері, а програми зберігалися на перфокартах, головним інструментом в програмуванні були глобальні змінні. З перейняв цю особливість і декілька її удосконалив: програмістові доводилося принаймні оголошувати тип глобальної змінної. Звичайно ж, при використанні глобальних змінних проблема полягала в тому, що будь-яка функція могла привести до широкомасштабних побічних ефектів, змінивши глобальний стан системи. У Java єдиним глобальним простором імен є класова ієрархія. У цій мові просто неможливо створити глобальну змінну, що не належить жодному з класів. Інша не дуже хороша конструкція традиційних мов програмування - оператор goto, призначений для передачі управління. Всім нам на перших заняттях по програмуванню говорили, що можна обійтися без цього оператора, погіршуючого структуру програми і що робить її нелегкою для читання.
До того, як в C++ з'явився механізм роботи з виключеннями, goto активно використовувався для виходу з циклів у виняткових ситуаціях. У Java оператора goto немає. У ній є зарезервоване ключове слово goto, але це зроблено лише щоб уникнути можливої плутанини - для того, щоб утримати програмістів від його використання. Зате в Java є оператори continue і break з міткою, що заповнюють відсутність goto в тих єдиних випадках, коли використання останній було б виправдано. А могутній добре певний вбудований в Java механізм виключень робить непотрібним використання goto в решті всіх ситуацій. Покажчики або адреси в пам'яті - найбільш могутня і найбільш небезпечна межа C++. Причиною більшості помилок в сьогоднішньому коді є саме неправильна робота з покажчиками. Наприклад, одна з типових помилок - прорахуватися на одиницю у розмірі масиву і зіпсувати вміст елементу пам'яті, розташованої услід за ним.
Хоча в Java дескриптори об'єктів і реалізовані у вигляді покажчиків, в ній відсутні можливості працювати безпосередньо з покажчиками. Ви не можете перетворити ціле число в покажчик, а також звернутися до довільної адреси пам'яті. Розподіл пам'яті. В строю небезпечних якостей C++ рука в руку з покажчиками йде розподіл пам'яті. Розподіл пам'яті в З, а значить і в C++, спирається на інь і янь ненадійного кода - на виклики бібліотечних функцій malloc() і free(). Якщо ви вiдключите free() з покажчиком на блок пам'яті, який ви вже звільнили раніше, або з покажчиком, пам'ять для якого ніколи не віделялась - готуйтеся до гіршого. Зворотна проблема, коли ви просто забуваєте викликати free(), щоб звільнити непотрібний більше блок пам'яті, набагато підступніша. "Витік пам'яті" (memory leak) приводить до поступового уповільнення роботи програми у міру того, як системі віртуальної пам'яті доводиться скидати на диск невживані сторінки із сміттям.
І, нарешті, коли всі системні ресурси вичерпані, програма несподівано аварійно завершується, а ви починаєте сушити голову над цією проблемою. У C++ додані два оператора-new і delete, які використовуються багато в чому аналогічно функціям malloc() і free(). Програміст, як і раніше, відповідає за те, щоб кожен невживаний об'єкт, створений за допомогою оператора new, був знищений оператором delete. У Java немає функцій free(). Оскільки в ній кожна складна структура даних - це об'єкт, пам'ять під такі структури резервується в купі (heap) за допомогою оператора new. Реальні адреси пам'яті, виділені цьому об'єкту, можуть змінюватися під час роботи програми, але вам не потрібно про це турбуватися. Вам навіть не доведеться викликати free () або delete, оскільки Java-система з так званим складальником сміття.
C++ отримав в спадок від C звичайні типи даних останнього. Ці типи служать для представлення цілих і дійсних чисел різних розмірів і точності. До нещастя, реальний діапазон і точність цих типів коливається залежно від конкретної реалізації транслятора. Поведінка коду, який транслюється і виконується на одній машині, може відрізнятися при зміні платформи. Різні транслятори C++ можуть резервувати під цілий тип 16, 32 або 64 бита залежно від розрядності машинного слова.
У Java таке неможливе, оскільки в ній відсутні файли заголовків. Тип і видимість членів класу при трансляції вбудовуються всередину файлу *.class (файлу з байт-кодом). Інтерпретатор Java користується цією інформацією в процесі виконання коду, так що не існує способу дістати доступ до закритих змінних класу ззовні. Ненадійні структури. С++ намагається надати програмістові можливість інкапсуляції даних за допомогою оголошення структур (struct) і поліморфізм за допомогою об'єднань (union). Ці дві конструкції прикривають критичні і катастрофічні машинно-залежні обмеження за розміром і вирівнюванням даних. У Java немає конструкцій struct і union, все це об'єднано в концепції класів.
Допроцесорна обробка. Робота допроцесорна C++ якого полягає в пошуку спеціальних команд, що починаються з символу #. Ці команди дозволяють виконувати просту умовну трансляцію і розширення макроозначень. Java управляється з своїми завданнями без допомоги допроцесорна, замість прийнятого стилю визначення констант за допомогою директиви #define в ній використовується ключове слово final.