Microsoft Visual Basic — средство разработки программного обеспечения, разрабатываемое корпорацией Microsoft и включающее язык программирования и среду разработки. Язык Visual Basic унаследовал дух, стиль и отчасти синтаксис своего предка — языка Бэйсик, у которого есть немало диалектов. В то же время Visual Basic сочетает в себе процедуры и элементы объектно-ориентированных и компонентно-ориентированных языков программирования. Среда разработки VB включает инструменты для визуального конструирования пользовательского интерфейса.

Visual Basic считается хорошим средством быстрой разработки прототипов программы, для разработки приложений баз данных и вообще для компонентного способа создания программ, работающих под управлением операционных систем семейства Microsoft Windows.

Первое признание серьёзными разработчиками Visual Basic получил после выхода версии 3 — VB3. Окончательное признание как полноценного средства программирования для Windows — при выходе версии 5 — VB5. Версию VB6, входящую в состав Microsoft Visual Studio 6.0, стала по-настоящему зрелым и функционально богатым продуктом. После этого разработчики из Microsoft существенно изменили направление развития данной технологии.

Visual Basic .NET не позволяет программировать по-старому, ибо по сути является совершенно другим языком, таким же, как и любой другой язык программирования для платформы .NET. Индивидуальность языка, так же как и его преимущества (простота, скромность создания программ, лёгкость использования готовых компонент) при использовании в среде .NET не имеют такого значения, как раньше — всё сосредоточено на возможностях самой системы .NET, на её библиотеке классов. Поэтому сегодня (февраль 2008) нужно говорить о классическом Visual Basic, его диалектах Visual Basic for Applications (VBA) и Visual Basic Scripting Edition (VBScript) и о языке для платформы .NET — Visual Basic .NET.

Язык Visual Basic не стандартизован ни ANSI, ни ISO.

Эволюция Visual Basic
май 1991 — выпущен Visual Basic 1.0 для Microsoft Windows. За основу языка был взят синтаксис QBasic, а новшеством, принесшим затем языку огромную популярность, явился принцип связи языка и графического интерфейса. Этот принцип был разработан Аланом Купером (Alan Cooper) и реализован в прототипе Tripod (также известном как Ruby). Первый Visual Basic был интерпретатором.
сентябрь 1992 — выпущен Visual Basic 1.0 под DOS. Он не был полностью совместим с Windows-версией VB, поскольку по сути являлся следующей версией QuickBASIC и работал в текстовом режиме экрана.
ноябрь 1992 — выпущен Visual Basic 2.0. Среда разработки стала проще в использовании и работала быстрее.
летом 1993 — вышел в свет Visual Basic 3.0 в версиях Standard и Professional. Ко всему прочему, в состав поставки добавился движок для работы с базами данных Access.
август 1995 — Visual Basic 4.0 — версия, которая могла создавать как 32-х так и 16-разрядные Windows-программы. Кроме того, появилась возможность писать на VB классы, а также Visual Basic наконец-то стал полноценным компилятором, что значительно увеличило скорость выполнения программ.
февраль 1997 — Visual Basic 5.0 — начиная с этой версии, стало возможно, наряду с обычными приложениями, разрабатывать COM-компоненты. Скомпилировав такой компонент в OCX-файл и поставляя его, можно было предоставить свой объект управления не только конечному пользователю, но и другим разработчикам, после чего они могли интегрировать этот объект в свои приложения.
В середине 1998 — вышла Visual Basic 6.0. После этого Microsoft резко изменила политику в отношении языков семейства Basic. Вместо развития Visual Basic, был создан абсолютно новый язык Visual Basic.net, первая версия которого появилась в 2001. Это принципиально новый язык, имеющий, помимо синтаксиса, очень мало схожего с VB 6.0; и отличаясь от него также сильно, как в своё время, VB отличался от QBASIC. VB.NET сразу же занял место VB в Visual Studio, и на этом развитие классического Visual Basic остановилось.
В 2005 году вышла новая версия Visual Basic, в комплекте Visual Studio. Порадовала она новым интерфейсом и возможностями. Язык основан на Visual Basic.NET. Она не была классической версией VB.
В конце 2007 Microsoft выпустила новую версию Visual Basic — Visual Basic 2008, которая также была основана на Visual Basic.NET.

Основные разновидности Visual Basic

Классический Visual Basic (версии 5-6)
 
Visual Basic Classic

Этот язык очень сильно привязан к своей среде разработки и к операционной системе Windows, являясь исключительно инструментом написания Windows-приложений. Привязка к среде заключается в том, что существует большое количество средств, предназначенных для помощи и удобства программирования: встроенный отладчик, просмотр переменных и структур данных на лету, окно отладки, всплывающая подсказка при наборе текста программы (Intellisense). Все эти преимущества делают бесполезным и даже невозможным использование Visual Basic вне среды разработки, например в обычном текстовом редакторе.

Visual Basic for Applications (VBA)

Это средство программирования, практически ничем не отличающееся от классического Visual Basic, которое предназначено для написания макросов и других прикладных программ для конкретных приложений. Наибольшую популярность получил благодаря своему использованию в пакете Microsoft Office. Широкое распространение Visual Basic for Applications в сочетании с изначально недостаточным вниманием к вопросам безопасности привело к широкому распространению макровирусов.

Особенности:
Оператор \ — деление нацело, любая дробная часть отсекается.
Перед выполнением операции a\b a и b округляются до целого.

Округление происходит до ближайшего целого числа, но, если дробная часть в точности равна 0.5, то округление происходит до ближайшего четного целого. Примеры:
19.5\1=20
2.5\1=2
−3.5\1=-4
19.5\2.5=10
19.5\1.5=10
21.4\2.5=10

Visual Basic Scripting Edition (VBScript)

Основная статья: Visual Basic Scripting Edition

Скриптовый язык, являющийся несколько усечённой версией обычного Visual Basic. Используется в основном для автоматизации администрирования систем Windows, а также для создания страниц ASP и сценариев для Internet Explorer.

Достоинства и недостатки

Достоинства
Высокая скорость создания приложений с графическим интерфейсом для MS Windows.
Простой синтаксис, позволяющий очень быстро освоить язык.
Возможность как компиляции в машинный код, так и интерпретации во время отладки.

Недостатки
Поддержка операционных систем только семейства Windows (Исключение — VB1 for DOS).
Отсутствие механизма наследования объектов. Существующие в языке наследование, позволяет наследовать только интерфейсы объектов, а не их самих. Таким образом, в унаследованом классе должны быть явно переписаны все функции базового класса. Также в унаследованном классе невозможно добавление каких-либо методов, присущих только даннному классу, то есть если абстрактный базовый класс содержит только два метода, то и производный класс содержит только два метода, не более и не менее того.
Требует установленных DLL для работы программы.

Критика
Часто критике подвергаются такие аспекты Visual Basic, как возможность отключить средства слежения за объявленными переменными, возможность неявного преобразования переменных, наличие типа данных «Variant». По мнению критиков, это даёт возможность писать крайне плохой код. С другой стороны, это можно рассматривать как плюс, так как VB не навязывает «хороший стиль», а даёт больше свободы программисту.
Отсутствие указателей, низкоуровневого доступа к памяти, ASM-вставок. Несморя на то, что парадигма Visual Basic позволяет среднему VB-программисту обходиться без всего этого, перечисленные вещи также нередко становятся объектами критики. И хотя, используя недокументированные возможности и определённые ухищрения, всё это можно реализовать и на VB; пользоваться этими трюками гораздо сложнее, чем, например, на Си++.

См. также
Visual Basic .NET
Gambas [1] — реализация BASIC для GNU/Linux, поддерживающая набор функциональности, близкий к классическому Visual Basic.
REALbasic [2] — RAD для GNU/Linux, с реализацией BASIC, обеспечивающей совместимость с Visual Basic
Jabaco(англ.) — язык с VisualBasic-подобным синтаксисом плюс среда разработки, исполняется под JVM

Ссылки
VisualBasic.Mapscape.Ru — Теория и практика программирования на Visual Basic. Статьи, исходники, утилиты для разработчика.
Bit.Pirit.Info — русскоязычный форум посвящённый программированию на Visual Basic 6.0 и .Net, VBA/VBS, ASP.Net.
VBNet.Ru — крупнейший русскоязычный сайт посвящённый программированию на Visual Basic, VBA, VBS, ASP, .Net.
VBStreets — русскоязычный сайт посвящённый программированию на Visual Basic.
Kbyte.Ru — русскоязычный сайт по программированию на Visual Basic, VBA, ASP/VBScript.
VBRussian.Ru- сайт посвящённый программированию на Visual Basic с большим количеством примеров и статей
Visual Basic FAQ — База готовых кодов на Visual Basic. Часто задаваемые вопросы.
[3]- самоучитель по Visual Basic
vbrus.narod.ru- статьи и примеры по VB6
visualprogs.medyal.ru- сайт по VB

Литература
Брайан Сайлер, Джефф Споттс Использование Visual Basic 6. Классическое издание = Special Edition Using Visual Basic 6. — М.: «Вильямс», 2007. — С. 832. — ISBN 0-7897-1542-2
Билл Семпф Microsoft Visual Basic 2005 для “чайников” = Visual Basic 2005 For Dummies. — М.: «Диалектика», 2006. — С. 288. — ISBN 0-7645-7728-X
Игорь Сафонов Visual Basic в задачах и примерах. — БХВ-Петербург. — СПб.: «БХВ-Петербург», 2008. — С. 400. — ISBN 978-5-94157-495-7

Java — объектно-ориентированный язык программирования, разрабатываемый компанией Sun Microsystems и официально выпущенный 23 мая 1995 года. В отношении произношения в русском языке, как и в ряде других, образовались две различные нормы — англоязычная /ˈdʒɑːvə/[1] и традиционно-национальная («Ява»), соответствующая традиционому произношению названия острова Ява.

Java — так называют не только сам язык, но и платформу для создания приложений уровня предприятий на основе данного языка.

Изначально язык программирования назывался Oak (русск. Дуб) и разрабатывался Джеймсом Гослингом для бытовой электроники, но впоследствии был переименован в Java и стал использоваться для написания клиентских приложений и серверного программного обеспечения. Назван в честь марки кофе Java, любимого программистами, поэтому на официальной эмблеме языка Java изображена чашка с дымящимся кофе.Содержание [убрать]
1 Основные особенности языка
2 История версий
2.1 Java 1.0
2.2 Java 2.0
2.3 Java 5
3 Классификация платформ Java
4 Java и Microsoft
5 Применения платформы Java
6 Основные возможности
7 Пространство имён
8 Пример программы
9 Основные идеи
9.1 Примитивные типы
9.1.1 Преобразования при математических операциях
9.2 Объектные переменные, объекты, ссылки и указатели
9.2.1 Дублирование ссылок и клонирование
9.2.2 Сборка мусора
9.3 Классы и функции
9.3.1 Статические методы и поля
9.3.2 Финальность
9.3.3 Абстрактность
9.3.4 Интерфейсы
9.3.4.1 Маркерные интерфейсы
9.3.5 Шаблоны в Java (generics)
9.3.6 Проверка принадлежности к классу
10 Библиотеки классов
11 Средства разработки ПО
12 Примечания
13 Литература
14 См. также
15 Ссылки

Основные особенности языка

Программы на Java транслируются в байт-код, выполняемый виртуальной java-машиной (JVM) — программой, обрабатывающей байтовый код и передающей инструкции оборудованию как интерпретатор, но с тем отличием, что байтовый код, в отличие от текста, обрабатывается значительно быстрее.

Достоинство подобного способа выполнения программ — в полной независимости байт-кода от ОС и оборудования, что позволяет выполнять Java-приложения на любом устройстве, которое поддерживает виртуальную машину. Другой важной особенностью технологии Java является гибкая система безопасности благодаря тому, что исполнение программы полностью контролируется виртуальной машиной. Любые операции, которые превышают установленные полномочия программы (например, попытка несанкционированного доступа к данным или соединения с другим компьютером) вызывают немедленное прерывание. Это позволяет пользователям загружать программы, написанные на Java, на их компьютеры (или другие устройства, например, мобильные телефоны) из неизвестных источников, при этом не опасаясь заражения вирусами, пропажи ценной информации, и т. п.

Часто к недостаткам концепции виртуальной машины относят то, что исполнение байт-кода виртуальной машиной может снижать производительность программ и алгоритмов, реализованных на языке Java. Данное утверждение было справедливо для первых версий виртуальной машины Java, однако в последнее время оно практически потеряло актуальность. Этому способствовал ряд усовершенствований: применение технологии JIT (Just-In-Time compilation), позволяющей переводить байт-код в машинный код во время исполнения программы с возможностью сохранения версий класса в машинном коде, широкое использование native-кода в стандартных библиотеках, а также аппаратные средства, обеспечивающие ускоренную обработку байт-кода (например, технология Jazelle, поддерживаемая некоторыми процессорами фирмы ARM).

Идеи, заложенные в концепцию и различные реализации JVM, вдохновили множество энтузиастов на расширение перечня языков, которые могли бы быть использованы для создания программ, исполняемых в среде JVM[2]. Эта идея перекликается с концепцией CLI, заложенной в основу платформы .NET компании Microsoft.

История версий

Java 1.0

Разработка Java началась в 1990 году, первая официальная версия — Java 1.0, — была выпущена только в 1995 году.

Java 2.0

К 1998 году была разработана обновлённая спецификация JDK 1.2, вышедшая под наименованием Java 2. Собственно языковых изменений в данной версии не появилось. Платформа получила следующие дополнения:
Набор средств для создания визуального интерфейса пользователя Swing.
Коллекции.
Поддержка файлов Policy и цифровых сертификатов пользователя.
Библиотека Accessibility.
Java 2D.
Поддержка технологии drag-and-drop.
Полная поддержка Unicode, включая поддержку ввода на японском, китайском и корейском языках.
Поддержка воспроизведения аудио-файлов нескольких популярных форматов.
Полная поддержка технологии CORBA.
JIT-компилятор, улучшенная производительность.
Усовершенствования инструментальных средств JDK, в том числе поддержка профилирования Java-программ

Java 5

Спецификация Java 5 была выпущена в сентябре 2004 года. В данной версии разработчики внесли в язык целый ряд принципиальных дополнений:
Перечислимые типы (enum). Ранее отсутствовавшие в Java типы оформлены по аналогии с C++, но при этом имеют ряд дополнительных возможностей.
Перечислимый тип является полноценным классом Java, то есть может иметь конструктор, поля, методы, в том числе скрытые и абстрактные.
Перечисление может реализовывать интерфейсы.
Для перечислений имеются встроенные методы, дающие возможность получения значений типа по имени, символьных значений, соответствующих именам, преобразования между номером и значением, проверки типа на то, что он является перечислимым.
Аннотации — возможность добавления в текст программы метаданных, не влияющих на выполнение кода, но допускающих использование для получения различных сведений о коде и его исполнении. Одновременно выпущен инструментарий для использования аннотированного кода. Одно из применений аннотаций — упрощение создания тестовых модулей для Java-кода.
Средства обобщённого программирования (generics) — механизм, аналогичный шаблонам в C++ (позже также появились и в C#), дающий возможность создавать классы и методы с полями и параметрами произвольного типа. С использованием данного механизма реализованы новые версии коллекций стандартной библиотеки Java.
Методы с неопределённым числом параметров.
Autoboxing/Unboxing — автоматическое преобразование между скалярными типами Java и соответствующими типами-врапперами (например, между int — Integer). Наличие такой возможности упрощает код, поскольку исключает необходимость в выполнении явных преобразований типов в очевидных случаях.
Разрешён импорт статических переменных.
В язык введён цикл по коллекции объектов (итератор).

Классификация платформ Java

Внутри Java существуют три основных семейства технологий:
J2EE или Java EE (начиная с v1.5) — Java Enterprise Editon, для создания программного обеспечения уровня предприятия;
J2SE или Java SE (начиная с v1.5) — Java Standard Editon, для создания пользовательских приложений, в первую очередь — для настольных систем;
J2ME, Java ME или Java Micro Edition, для использования в устройствах, ограниченных по вычислительной мощности, в том числе мобильных телефонах, PDA, встроенных системах

Самыми популярными считаются серверные технологии семейства J2EE.

Последним релизом является версия 1.6, в которой было произведено улучшение системы безопасности, улучшение поддержки XML, а также добавлена поддержка скриптового языка JavaScript на основе механизма Mozilla Rhino (англ.), улучшена интеграция с рабочим столом, добавлены некоторые новые возможности в создании графических интерфейсов.

Java и Microsoft

Компанией Microsoft была разработана собственная реализация JVM (MSJVM), включавшаяся в состав различных ОС, начиная с Windows 95. MSJVM была близка к спецификации Sun Microsystems v.1.1.3, но не соответствовала ей по ряду принципиальных характеристик (в частности, по отсутствию поддержки технологий RMI и JNI и по наличию нестандартных расширений). Впоследствии это явилось поводом для судебных исков со стороны Sun Microsystems к Microsoft. Суд принял сторону компании Sun Microsystems. В конечном счёте между двумя компаниями была достигнута договорённость о возможности продления срока официальной поддержки пользователей нестандартной Microsoft JVM до конца 2007 года, но не более[3]. В настоящее время компанией Microsoft для платформы .NET предлагается Java-подобный язык J#, не соответствующий официальной спецификации языка Java.

[править]
Применения платформы Java

Следующие успешные проекты реализованы с привлечением Java (J2EE) технологий: Amazon, eBay, Flickr, Yandex, LinkedIn[4].

Следующие компании в основном фокусируются на Java (J2EE) технологиях, а не на .NET, хотя имеют дело также и с последними: SAP, IBM, Oracle.

Основные возможности
автоматическое управление памятью
расширенные возможности обработки исключительных ситуаций;
богатый набор средств фильтрации ввода/вывода;
набор стандартных коллекций, таких как массив, список, стек и т. п.;
наличие простых средств создания сетевых приложений (в том числе с использованием протокола RMI);
наличие классов, позволяющих выполнять HTTP-запросы и обрабатывать ответы;
встроенные в язык средства создания многопоточных приложений;
унифицированный доступ к базам данных на основе JDBC и SQLJ.
поддержка шаблонов (начиная с версии 1.5)

Пространство имён
Основная статья: Пространство имён (программирование)

Идея пространств имён воплощена в Java-пакетах.

Пример программы

Программа, выводящая «Hello, World!»:
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println(“Hello, World!”);
    }
}

Пример использования шаблонов:
import java.util.*;
public class Sample {
    public static void main(String[] args) {
        // Создание объекта по шаблону.
        List<String> strings = new LinkedList<String>();
        strings.add(“Hello”);
        strings.add(“world”);
        strings.add(“!”);
        for (String s : strings) {
            System.out.print(s);
            System.out.print(” “);
        }
    }
}

Основные идеи

Примитивные типы

В языке Java только 8 скалярных типов: boolean, byte, char, short, int, long, float, double.
Классы-обёртки примитивных типов
Byte
Short
Integer
Long
Float
Double
Boolean
Character

Длины и диапазоны значений примитивных типов определяются стандартом, а не реализацией и приведены в таблице. Тип char сделали двухбайтовым для удобства локализации (один из идеологических принципов Java): когда складывался стандарт, уже существовал Unicode-16, но не Unicode-32. Поскольку в результате не осталось однобайтового типа, добавили новый тип byte. Типы float и double могут иметь специальные значения ,  и «не число» (NaN). Для типа double они обозначаются Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NaN; для типа float — так же, но с приставкой Float вместо Double. Минимальные положительные значения, принимаемые типами float и double, тоже стандартизованы.Тип    Длина (в байтах)    Диапазон или набор значений
boolean    не определено    true, false
byte    1    −128..127
char    2    0..216-1, или 0..65535
short    2    −215..215-1, или −32768..32767
int    4    −231..231-1, или −2147483648..2147483647
long    8    −263..263-1, или примерно −9.2·1018..9.2·1018
float    4    -(2-2-23)·2127..(2-2-23)·2127, или примерно −3.4·1038..3.4·1038, а также , , NaN
double    8    -(2-2-52)·21023..(2-2-52)·21023, или примерно −1.8·10308..1.8·10308, а также , , NaN

Такая жёсткая стандартизация была необходима, чтобы сделать язык платформенно-независимым, что является одним из идеологических требований к Java и одной из причин её успеха. Тем не менее одна небольшая проблема с платформенной независимостью всё же осталась. Некоторые процессоры используют для промежуточного хранения результатов 10-байтовые регистры или другими способами улучшают точность вычислений. Для того, чтобы сделать Java максимально совместимой между разными системами, в ранних версиях любые способы повышения точности вычислений были запрещены. Однако это приводило к снижению быстродействия. Выяснилось, что ухудшение точности ради платформенной независимости мало кому нужно, тем более если за это приходится платить замедлением работы программ. После многочисленных протестов этот запрет отменили, но добавили ключевое слово strictfp, запрещающее повышение точности.

Преобразования при математических операциях

В языке Java действуют следующие правила:
Если один операнд имеет тип double, другой тоже преобразуется к типу double.
Иначе, если один операнд имеет тип float, другой тоже преобразуется к типу float.
Иначе, если один операнд имеет тип long, другой тоже преобразуется к типу long.
Иначе оба операнда преобразуется к типу int.

Последнее правило отличает Java от старых реализаций C и C++ и делает код более безопасным. Так, например, в языке Java после выполнения кода
short x = 50, y = 1000;
int z = x*y;

переменной z присваивается значение 50000, а не −15536, как в большинстве безнадёжно устаревших реализаций[источник?] C и C++. В программе, скомпилированной MS VC++, начиная с версии 7, а также многими другими современными компиляторами (gcc, Intel C++, Borland C++, Comeau и т. д.), значение будет также равно 50000.

Объектные переменные, объекты, ссылки и указатели

В языке Java имеются только динамически создаваемые объекты. Причем переменные объектного типа и объекты в Java — совершенно разные сущности. Переменные объектного типа являются ссылками, то есть неявными указателями на динамически создаваемые объекты. Это подчёркивается синтаксисом описания переменных. Так, в Java нельзя писать:
double a[10][20];
Foo b(30);

а нужно:
double[][] a = new double[10][20];
Foo b = new Foo(30);

При присваиваниях, передаче в подпрограммы и сравнениях объектные переменные ведут себя как указатели, то есть присваиваются, копируются и сравниваются адреса объектов. А при доступе с помощью объектной переменной к полям данных или методам объекта не требуется никаких специальных операций разыменовывания — этот доступ осуществляется так, как если бы объектная переменная была самим объектом.

Объектными являются переменные любого типа, кроме простых числовых типов. Явных указателей в Java нет. В отличие от указателей C, C++ и других языков программирования, ссылки в Java в высокой степени безопасны благодаря жёстким ограничениям на их использование, в частности:
Нельзя преобразовывать объект типа int или любого другого примитивного типа в указатель или ссылку и наоборот.
Над ссылками запрещено выполнять операции ++, −−, +, − или любые другие арифметические операции.
Преобразование типов между ссылками жёстко регламентировано. За исключением ссылок на массивы, разрешено преобразовывать ссылки только между наследуемым типом и его наследником, причём преобразование наследуемого типа в наследующий должно быть явно задано и во время выполнения производится проверка его осмысленности. Преобразования ссылок на массивы разрешены лишь тогда, когда разрешены преобразования их базовых типов, а также нет конфликтов размерности.
В Java нет операций взятия адреса (&) или взятия объекта по адресу (*). Звёздочка в Java означает умножение, и только. Амперсанд (&) означает всего лишь «побитовое и» (двойной амперсанд — «логическое и»).

Благодаря таким специально введенным ограничениям в Java невозможно прямое манипулирование памятью на уровне физических адресов (хотя ссылки, не указывающие ни на что, есть: значение такой ссылки обозначается null).

Дублирование ссылок и клонирование

Из-за того, что объектные переменные являются ссылочными, при присваивании не происходит копирования объекта. Так, если написать
Foo foo, bar;

bar = foo;

то произойдет копирование адреса из переменной foo в переменную bar. То есть foo и bar будут указывать на одну и ту же область памяти, то есть на один и тот же объект; попытка изменить поля объекта, на который ссылается переменная foo, будет менять объект, с которым связана переменная bar, и наоборот. Если же необходимо получить именно ещё одну копию исходного объекта, пользуются или методом (функцией-членом, в терминологии C++) clone(), создающим копию объекта, или же копирующим конструктором.

Метод clone() требует, чтобы класс реализовывал интерфейс Cloneable (об интерфейсах см. ниже). Если класс реализует интерфейс Cloneable, по умолчанию clone() копирует все поля (мелкая копия). Если требуется не копировать, а клонировать поля (а также их поля и так далее), надо переопределять метод clone(). Определение и использование метода clone() часто является нетривиальной задачей [1].

Сборка мусора

В языке Java невозможно явное удаление объекта из памяти — вместо этого реализована сборка мусора. Традиционным приёмом, дающим сборщику мусора «намёк» на освобождение памяти, является присваивание переменной пустого значения null. Это, однако, не значит, что объект, заменённый значением null, будет непременно и немедленно удалён. Данный приём всего лишь устраняет ссылку на объект, то есть отвязывает указатель от объекта в памяти. При этом следует учитывать, что объект не будет удален сборщиком мусора, пока на него указывает хотя бы одна ссылка из используемых переменных или объектов. Существуют также методы для инициации принудительной сборки мусора, но не гарантируется, что они будут вызваны исполняющей средой, и их не рекомендуется использовать для обычной работы.

Классы и функции

Java не является процедурным языком: любая функция может существовать только внутри класса. Это подчёркивает терминология языка Java, где нет понятий «функция» или «функция-член» (англ. member function), а только метод. В методы превратились и стандартные функции. Например, в Java нет функции sin(), а есть метод Math.sin() класса Math (содержащего, кроме sin(), методы cos(), exp(), sqrt(), abs() и многие другие).

Статические методы и поля

Для того чтобы не надо было создавать объект класса Math (и других аналогичных классов) каждый раз, когда надо вызвать sin() (и другие подобные функции), введено понятие статических методов (англ. static method; иногда в русском языке они называются статичными). Статический метод (отмечаемый ключевым словом static в описании) можно вызвать, не создавая объекта его класса. Поэтому можно писать
double x = Math.sin(1);

вместо
Math m = new Math();
double x = m.sin(1);

Ограничение, накладываемое на статические методы, заключается в том, что в объекте this они могут обращаться только к статическим полям и методам.

Статические поля имеют тот же смысл, что и в C++: каждое существует только в единственном экземпляре.

Финальность

Ключевое слово final (финальный) означает разные вещи при описании переменной, метода или класса. Финальная переменная (именованная константа) инициализируется при описании и дальше не может быть изменена. Финальный метод не может быть переопределён при наследовании. Финальный класс не может иметь наследников вообще.

Абстрактность

В Java методы, не объявленные явно как final или private, являются виртуальными в терминологии C++: при вызове метода, по-разному определённого в базовом и наследующем классах, всегда производится проверка времени выполнения.

Абстрактным методом (описатель abstract) в Java называется метод, для которого заданы параметры и тип возвращаемого значения, но не тело. Абстрактный метод определяется в классах-наследниках. В C++ то же самое называется чисто виртуальной функцией. Для того чтобы в классе можно было описывать абстрактные методы, сам класс тоже должен быть описан как абстрактный. Объекты абстрактного класса создавать нельзя.

Интерфейсы

Высшей степенью абстрактности в Java является интерфейс (interface). Все методы интерфейса абстрактны: описатель abstract даже не требуется. Интерфейс не является классом. Класс может наследовать, или расширять (extends) другой класс или реализовывать (implements) интерфейс. Кроме того, интерфейс может наследовать, или расширять другой интерфейс.

В Java класс не может наследовать более одного класса, зато может реализовывать сколько угодно интерфейсов.

Интерфейсы можно передавать методам как параметры, но нельзя создавать объекты их типов.

Маркерные интерфейсы

В Java есть некоторые интерфейсы, которые не содержат методов для реализации, а специальным образом обрабатываются JVM. Это интерфейсы:
java.lang.Cloneable
java.io.Serializable
java.rmi.Remote

Шаблоны в Java (generics)

Начиная с версии Java 5 в языке появился механизм обобщённого программирования — шаблоны, внешне близкие к шаблонам C++. С помощью специального синтаксиса в описании классов и методов можно указать параметры-типы, которые внутри описания могут использоваться в качестве типов полей, параметров и возвращаемых значений методов.
// Объявление обобщённого класса
class GenericClass<E>
{
  E getFirst() { … }
  void add(E obj) { … }
}
 
// Использование обобщённого класса в коде
GenericClass <String> var = new GenericClass<String>();
var.add(“qwerty”);
String p = var.getFirst();

Допускается обобщённое объявление классов, интерфейсов и методов. Кроме того, синтаксис поддерживает ограниченные объявления типов-параметров: указание в объявлении конструкции вида <T extends A & B & C…> требует, чтобы тип-параметр T реализовывал интерфейсы A, B, C и так далее, а конструкция <T super C> требует, чтобы тип-параметр T был типом C или одним из его предков.

В отличие от шаблонов C#, шаблоны Java не поддерживаются средой исполнения — компилятор просто создаёт байт-код, в котором никаких шаблонов уже нет. Реализация шаблонов в Java принципиально отличается от реализации аналогичных механизмов в C++: компилятор не порождает для каждого случая использования шаблона отдельный вариант класса или метода-шаблона, а просто создаёт одну реализацию байт-кода, содержащую необходимые проверки и преобразования типов. Это приводит к ряду ограничений использования шаблонов в программах на Java.

Проверка принадлежности к классу

В Java можно явно проверить, к какому классу принадлежит объект. Выражение foo instanceof Foo истинно, если объект foo принадлежит классу Foo или его наследнику, или реализует интерфейс Foo (или, в общем виде, наследует класс, который реализует интерфейс, который наследует Foo).

Далее, функция getClass(), определённая для всех объектов, выдаёт объект типа Class. Эти объекты можно сравнивать. Так, например, foo.getClass()==bar.getClass() будет истинно, если объекты foo и bar принадлежат в точности к одному классу (но это не означает что это два одинаковых объекта).

Кроме того, объект типа Class любого типа можно получить так: Integer.class, Object.class.

Однако прямое сравнение классов не всегда является оптимальным средством проверки на принадлежность к классу. Зачастую вместо него используют функцию isAssignableFrom(). Эта функция определена у объекта типа Class и принимает объект типа Class в качестве параметра. Таким образом, вызов Foo.class.isAssignableFrom(Bar.class) вернёт true в случае, если Foo является предком класса Bar. Так как все объекты являются потомками типа Object, вызов Object.class.isAssignableFrom() всегда вернёт true. В паре с упомянутыми функциями объекта типа Class используются также функции isInstance() (эквивалентно instanceof), а также cast() (преобразует параметр в объект выбранного класса).

Библиотеки классов
JDK — содержит набор базовых классов для всего ПО на платформах Java SE и Java EE
CDK — для создания химического ПО
MARF — модульная библиотека для распознавания аудио

Средства разработки ПО
JDK — помимо набора библиотек для платформ Java SE и Java EE содержит компилятор командной строки javac и набор утилит, также работающих в режиме командной строки.
NetBeans IDE — бесплатная интегрированная среда разработки для всех платформ Java — Java ME, Java SE и Java EE. Пропагандируется Sun Microsystems, разработчиком Java, как базовое средство для разработки ПО на языке Java и других языках (C, C++, Ruby, Fortran и др.).
Eclipse — бесплатная интегрированная среда разработки для Java SE и Java EE. Ведутся работы по поддержке в Eclipse платформы Java ME. Пропагандируется IBM, одним из важнейших разработчиков корпоративного ПО, как базовое средство для разработки ПО на языке Java и других языках (C, C++, Ruby, Fortran и др.)
IntelliJ IDEA — коммерческая среда разработки для платформ Java SE, Java EE и Java ME.

Примечания
↑ java. Merriam-Webster Online Dictionary. Merriam-Webster. — Английская норма произношения слова «Java». (Проверено 21 мая 2009.)
↑ Robert Tolksdorf. Programming languages for the Java Virtual Machine JVM (англ.). is-research GmbH. — Онлайн-каталог альтернативных языков и языковых расширений для JVM. (Проверено 27 апреля 2009.)
↑ Microsoft Java Virtual Machine Support (англ.). Microsoft (2003-09-12). — Официальное заявление Microsoft о программе поддержки MSJVM. (Проверено 27 апреля 2009.)
↑ Brian Guan. The LinkedIn Blog. Blog Archive. Grails at LinkedIn. (англ.). LinkedIn.com (2008-06-11). — История создания системы LinkedIn на основе Java-технологии Grails. (Проверено 27 апреля 2009.)

Литература
Монахов Вадим Язык программирования Java и среда NetBeans, 2-е издание. — СПб.: «БХВ-Петербург», 2009. — С. 720. — ISBN 978-5-9775-0424-9
Джошуа Блох. Java. Эффективное программирование = Effective Java. — М.: «Лори», 2002. — С. 224. — ISBN 5-85582-169-2
Кей С. Хорстманн, Гари Корнелл. Java 2. Библиотека профессионала, том 1. Основы = Core Java™ 2, Volume I–Fundamentals. — 7-е изд. — М.: «Вильямс», 2007. — С. 896. — ISBN 0-13-148202-5
Кей С. Хорстманн, Гари Корнелл. Java 2. Библиотека профессионала, том 2. Тонкости программирования = Core Java™ 2, Volume II–Advanced Features. — 7-е изд. — М.: «Вильямс», 2007. — С. 1168. — ISBN 0-13-111826-9
Брюс Эккель. Философия Java = Thinking in Java. — 3-е изд.. — СПб.: «Питер», 2003. — С. 976. — ISBN 5-88782-105-1
Герберт Шилдт, Джеймс Холмс. Искусство программирования на Java = The Art of Java. — М.: «Диалектика», 2005. — С. 336. — ISBN 0-07-222971-3
Любош Бруга. Java по-быстрому: Практический экспресс-курс = Luboš Brůha. Java Hotová řešení.. — М.: Наука и техника, 2006. — С. 369. — ISBN 5-94387-282-5

Си++ (англ. C++) — компилируемый строго типизированный язык программирования общего назначения. Поддерживает разные парадигмы программирования: процедурную, обобщённую, функциональную; наибольшее внимание уделено поддержке объектно-ориентированного программирования.

Название «Си++» происходит от Си, в котором унарный оператор ++ обозначает инкремент переменной.

В 1990-х годах язык стал одним из наиболее широко применяемых языков программирования общего назначения.

При создании Си++ стремились сохранить совместимость с языком Си. Большинство программ на Си будут исправно работать и с компилятором Си++. Си++ имеет синтаксис, основанный на синтаксисе Си.Содержание [убрать]
1 Философия Си++
2 История
2.1 История названия
3 Технический обзор
4 Новые возможности по сравнению с Си
5 Не объектно-ориентированные возможности
6 Стандартная библиотека
7 Объектно-ориентированные особенности языка
7.1 Инкапсуляция
7.2 Описание функций в теле класса
7.3 Конструкторы и деструкторы
7.4 Другие возможности функций-членов
7.5 Наследование
7.6 Полиморфизм
7.7 Друзья
8 Будущее развитие
8.1 Ключевое слово export
9 Си++ не включает в себя Си
10 Примеры программ на Си++
10.1 Пример № 1
10.2 Пример № 2
10.3 Пример № 3
10.4 Пример № 4
11 Сравнение C++ с языками Java и C#
12 Достоинства и недостатки языка
12.1 Достоинства
12.2 Недостатки
13 Примечания
14 См. также
15 Ссылки
16 Литература

[править]
Философия Си++

В книге «Дизайн и эволюция языка C++» Бьёрн Страуструп описывает принципы, которых он придерживался при проектировании Си++.[1] Эти принципы объясняют, почему Си++ именно такой, какой он есть. Некоторые из них:
Получить универсальный язык со статическими типами данных, эффективностью и переносимостью языка Си.
Непосредственно и всесторонне поддерживать множество стилей программирования, в том числе процедурное программирование, абстракцию данных, объектно-ориентированное программирование и обобщённое программирование.
Дать программисту свободу выбора, даже если это даст ему возможность выбирать неправильно.
Максимально сохранить совместимость с Си, тем самым делая возможным лёгкий переход от программирования на Си.
Избежать разночтений между Си и C++: любая конструкция, которая допустима в обоих этих языках, должна в каждом из них обозначать одно и то же и приводить к одному и тому же поведению программы.
Избегать особенностей, которые зависят от платформы или не являются универсальными.
Никакое языковое средство не должно приводить к снижению производительности программ, не использующих его.
Не требовать слишком усложнённой среды программирования.

[править]
История

Язык возник в начале 1980-х годов, когда сотрудник фирмы Bell Laboratories Бьёрн Страуструп придумал ряд усовершенствований к языку Си под собственные нужды. До начала официальной стандартизации язык развивался в основном силами Страуструпа в ответ на запросы программистского сообщества. В 1998 году был ратифицирован международный стандарт языка Си++: ISO/IEC 14882:1998 «Standard for the C++ Programming Language»; после принятия технических исправлений к стандарту в 2003 году — нынешняя версия этого стандарта — ISO/IEC 14882:2003.

Страуструп начал работать над «Си с классами» в 1979 году. Идея создания нового языка берёт начало от опыта программирования Страуструпа для диссертации. Он обнаружил, что язык моделирования Симула (Simula) имеет такие возможности, которые были бы очень полезны для разработки большого программного обеспечения, но работает слишком медленно. В то же время язык BCPL достаточно быстр, но слишком близок к языкам низкого уровня и не подходит для разработки большого программного обеспечения. Страуструп начал работать в Bell Labs над задачами теории очередей (в приложении к моделированию телефонных вызовов). Попытки применения существующих в то время языков моделирования оказались неэффективными. Вспоминая опыт своей диссертации, Страуструп решил дополнить язык Си (преемник BCPL) возможностями, имеющимися в языке Симула. Язык Си, будучи базовым языком системы UNIX, на которой работали компьютеры Bell, является быстрым, многофункциональным и переносимым. Страуструп добавил к нему возможность работы с классами и объектами. В результате, практические задачи моделирования оказались доступными для решения как с точки зрения времени разработки (благодаря использованию Симула-подобных классов) так и с точки зрения времени вычислений (благодаря быстродействию Си). В начале в Си были добавлены классы (с инкапсуляцией), производные классы, строгая проверка типов, inline-функции и аргументы по умолчанию.

Разрабатывая Си с классами (позднее Си++), Страуструп также написал программу cfront — транслятор, перерабатывающий исходный код Си с классами в исходный код простого Си. Новый язык, неожиданно для автора, приобрёл большую популярность среди коллег и вскоре Страуструп уже не мог лично поддерживать его, отвечая на тысячи вопросов.

В 1983 году произошло переименование языка из Си с классами в Си++. Кроме того, в него были добавлены новые возможности, такие как виртуальные функции, перегрузка функций и операторов, ссылки, константы, пользовательский контроль над управлением свободной памятью, улучшенная проверка типов и новый стиль комментариев (//). Его первый коммерческий выпуск состоялся в октябре 1985 года. В 1985 году вышло также первое издание «Языка программирования Си++», обеспечивающее первое описание этого языка, что было чрезвычайно важно из-за отсутствия официального стандарта. В 1989 году состоялся выход Си++ версии 2.0. Его новые возможности включали множественное наследование, абстрактные классы, статические функции-члены, функции-константы и защищённые члены.

В 1990 году вышло «Комментированное справочное руководство по C++», положенное впоследствии в основу стандарта. Последние обновления включали шаблоны, исключения, пространства имён, новые способы приведения типов и булевский тип.

Стандартная библиотека Си++ также развивалась вместе с ним. Первым добавлением к стандартной библиотеке Си++ стали потоки ввода/вывода, обеспечивающие средства для замены традиционных функций Си printf и scanf. Позднее самым значительным развитием стандартной библиотеки стало включение в неё Стандартной библиотеки шаблонов.

После многих лет работы совместный комитет ANSI-ISO стандартизировал Си++ в 1998 году (ISO/IEC 14882:1998 — Язык программирования Си++). В течение нескольких лет после официального выхода стандарта комитет обрабатывал сообщения об ошибках и в итоге выпустил исправленную версию стандарта Си++ в 2003 году. В настоящее время рабочая группа МОС (ISO) работает над новой версией стандарта под кодовым названием C++09 (ранее известный как C++0X), который должен выйти в 2009 году.

Никто не обладает правами на язык Си++, он является свободным. Однако сам документ стандарта языка (за исключением черновиков) не доступен бесплатно.

[править]
История названия

Название «Си++» было придумано Риком Масситти (Rick Mascitti) и впервые было использовано в декабре 1983 года. Ранее, на этапе разработки, новый язык назывался «Си с классами».

Имя, получившееся в итоге, происходит от оператора Си «++» (увеличение значения переменной на единицу) и распространённому способу присвоения новых имён компьютерным программам, заключающемся в добавлении к имени символа «+» для обозначения улучшений (например «Википедия+»). Согласно Страуструпу, «это название указывает на эволюционную природу изменений Си». Выражением «С+» назывался более ранний, не связанный с Си++, язык программирования.

Некоторые программисты на Си могут заметить, что если выполняются выражения x=3; y=x++; то в результате получится x=4 и y=3, потому что x увеличивается только после присвоения его y. Однако если второе выражение будет y=++x; то получится x=4 и y=4.

Исходя из этого, можно сделать вывод, что логичнее было бы назвать язык не Си++, а ++Си. Однако оба выражения c++ и ++c увеличивают c, а кроме того выражение c++ более распространено.

Педанты также могут заметить, что введение языка Си++ не изменяет самого Си, поэтому самым точным именем было бы «С+1».

[править]
Технический обзор

Стандарт Си++ на 1998 год состоит из двух основных частей: ядра языка и стандартной библиотеки.

Стандартная библиотека Си++ вобрала в себя разрабатывавшуюся одновременно со стандартом библиотеку шаблонов STL. Сейчас название STL официально не употребляется, однако в кругах программистов на Си++ это название используется для обозначения части стандартной библиотеки, содержащей определения шаблонов контейнеров, итераторов, алгоритмов и функторов.

Стандарт Си++ содержит нормативную ссылку на стандарт Си от 1990 года и не определяет самостоятельно те функции стандартной библиотеки, которые заимствуются из стандартной библиотеки Си.

Кроме того, существует огромное количество библиотек Си++, не входящих в стандарт. В программах на Си++ можно использовать многие библиотеки Си.

Стандартизация определила язык программирования Си++, однако за этим названием могут скрываться также неполные, ограниченные, достандартные варианты языка. В первое время язык развивался вне формальных рамок, спонтанно, по мере ставившихся перед ним задач. Развитию языка сопутствовало развитие кросс-компилятора cfront. Новшества в языке отражались в изменении номера версии кросс-компилятора. Эти номера версий кросс-компилятора распространялись и на сам язык, но применительно к настоящему времени речь о версиях языка Си++ не ведут.

[править]
Новые возможности по сравнению с Си

Имеется викиучебник по теме:
Основные отличия Си++ от Си

Нововведениями Си++ в сравнении с Си являются:
поддержка объектно-ориентированного программирования;
поддержка обобщённого программирования через шаблоны;
дополнительные типы данных;
исключения;
пространства имён;
встраиваемые функции;
перегрузка операторов;
перегрузка имён функций;
ссылки и операторы управления свободно распределяемой памятью;
дополнения к стандартной библиотеке.

Язык Си++ во многом является надмножеством Си. Новые возможности Си++ включают объявления в виде выражений, преобразования типов в виде функций, операторы new и delete, тип bool, ссылки, расширенное понятие константности, подставляемые функции, аргументы по умолчанию, переопределения, пространства имён, классы (включая и все связанные с классами возможности, такие как наследование, функции-члены, виртуальные функции, абстрактные классы и конструкторы), переопределения операторов, шаблоны, оператор ::, обработку исключений, динамическую идентификацию и многое другое. Язык Си++ также во многих случаях строже относится к проверке типов, чем Си.

В Си++ появились комментарии в виде двойной косой черты («//»), которые были в предшественнике Си — языке BCPL.

Некоторые особенности Си++ позднее были перенесены в Си, например ключевые слова const и inline, объявления в циклах for и комментарии в стиле Си++ («//»). В более поздних реализациях Си также были представлены возможности, которых нет в Си++, например макросы vararg и улучшенная работа с массивами-параметрами.

[править]
Не объектно-ориентированные возможности

В этом разделе описываются возможности, непосредственно не связанные с объектно-ориентированным программированием (ООП). Многие из них, однако, особенно важны в сочетании с ООП.
Описатель inline означает, что функция является хорошим кандидатом на оптимизацию, при которой в местах обращения к функции компилятор вставит тело этой функции, а не код вызова. Пример: inline double Sqr(double x) {return x*x;}. inline является не директивой, а рекомендацией компилятору — компилятор не обязан реализовывать подстановку тела для inline-функций, но может, исходя из заданных критериев оптимизации, выполнять подстановку тела для функций, которые не объявлены как inline.
Описатель volatile используется в описании переменных и информирует компилятор, что значение данной переменной может быть изменено способом, который компилятор не в состоянии отследить. Для переменных, объявленных volatile, компилятор не должен применять средства оптимизации, изменяющие положение переменной в памяти (например, помещающие её в регистр) или полагающиеся на неизменность значения переменной в промежутке между двумя присваиваниями ей значения.
Вместо функций malloc и free (которые оставлены только для обратной совместимости), введены новые операции new и delete. Если T — произвольный тип, то
new T выделяет память, достаточную для размещения одного объекта типа Т, возможно, инициализирует объект в этой памяти, и возвращает указатель типа Т*.
new T[n] выделяет память, достаточную для размещения n объектов типа Т, возможно, инициализирует каждый объект в этой памяти, и возвращает указатель типа Т*.
delete p — разрушает объект, на который ссылается указатель p, и освобождает область памяти, выделенную для него ранее операцией new T.
delete [] p — разрушает каждый объект в массиве, на который ссылается указатель p, и освобождает область памяти, выделенную для этого массива ранее операцией new T[n].

Операция delete проверяет, что её аргумент не NULL, в противном случае она ничего не делает. При создании и удалении экземпляров классов с помощью new и delete компилятор генерирует вызовы конструктора и деструктора класса (см. ниже).
Функции могут принимать аргументы по ссылке. Например, функция void f(int& x) {x=3;} присваивает своему аргументу значение 3. Функции также могут возвращать результат по ссылке, и ссылки могут быть вне всякой связи с функциями. Например, {double&b=a[3]; b=sin(b);} эквивалентно a[3]=sin(a[3]);. Ссылки в определённой степени сходны с указателями, со следующими особенностями: при описании ссылки инициализируются указанием на существующее значение данного типа; ссылка пожизненно указывает на один и тот же адрес; при обращении к ссылке операция * производится автоматически. Существуют и другие отличия в использовании указателей и ссылок.
Могут быть несколько функций с одним и тем же именем, но разными типами или количеством аргументов (перегрузка функций; при этом тип возвращаемого значения на перегрузку не влияет). Например, вполне можно писать:
void Print(int x);
void Print(double x);
void Print(int x, int y);
Один или несколько последних аргументов функции могут задаваться по умолчанию. К примеру, если функция описана как void f(int x, int y=5, int z=10) , вызовы f(1), f(1,5) и f(1,5,10) эквивалентны.
При описании функций отсутствие аргументов в скобках означает, в отличие от Си, что аргументов нет, а не то, что они неизвестны. Если аргументы неизвестны, надо пользоваться многоточием, например int printf(const char* fmt, …).
Можно описывать операции над новыми типами. К примеру, так:
struct Date {int day, month, year;};
void operator ++(struct Date& date);

Операции ничем не отличаются от (других) функций. Нельзя описывать операции над предопределёнными типами (скажем, переопределять умножение чисел); нельзя выдумывать новые операции, которых нет в Си++ (скажем, **); арность (количество параметров) и приоритет операций сохраняется (скажем, в выражении a+b*c сначала будет выполняться умножение, а потом сложение, к каким бы типам ни принадлежали a, b и c.) Можно переопределить операции [] (с одним параметром) и () (с любым числом параметров).
Добавлены пространства имён namespace. Например, если написать
namespace Foo {
   const int x=5;
   typedef int** T;
   void f(y) {return y*x};
   double g(T);
   …
}

то вне фигурных скобок мы должны обращаться к T,x, f, g как Foo::T, Foo::x, Foo::f, Foo::g. Если мы в каком-то файле хотим обращаться к ним непосредственно, мы можем написать
using namespace Foo;

Или же
using Foo::T;

Пространства имён нужны, чтобы не возникало коллизий между пакетами, имеющими совпадающие имена глобальных переменных, функций и типов. Специальным случаем является безымянное пространство имён
namespace {
    …
}

Все имена, описанные в нём, доступны в текущей единице трансляции и больше нигде.
Добавлен новый тип bool , имеющий значения true и false . Операции сравнения возвращают тип bool . Выражения в скобках после if , while приводятся к типу bool .
// означает, что вся оставшаяся часть строки является комментарием.
Добавлены шаблоны (template). Например, template<class T> T Min(T x, T y) {return x<y?x:y;} определяет функцию Min для любых типов. Шаблоны могут задавать не только функции, но и типы. Например, template<class T> struct Array{int len; T* val;}; определяет массив значений любого типа, после чего мы можем писать Array<float> x;
Введена стандартная библиотека шаблонов (STL, Standard Template Library), определяющая шаблоны и функции для векторов (одномерных массивов произвольной длины), множеств, ассоциативных массивов (map), списков, символьных строк, потоков ввода-вывода и другие шаблоны и функции.
Если описана структура, класс, объединение (union) или перечисление (enum), её имя является именем типа, например:
struct Time {
    int hh, mm, ss;
};
Time t1, t2;
Внутри класса можно описывать вложенные типы, как через typedef, так и через описание других классов, а также перечислений. Для доступа к таким типам вне класса, к имени типа добавляется имя класса и два двоеточия:
struct S {
    typedef int** T;
    T x;
};
S::T y;

[править]
Стандартная библиотека

Стандартная библиотека Си++ включает стандартную библиотеку Си с небольшими изменениями, которые делают её более подходящей для языка Си++. Другая большая часть библиотеки Си++ основана на Стандартной Библиотеке Шаблонов (STL). Она предоставляет такие важные инструменты, как контейнеры (например, векторы и списки) и итераторы (обобщённые указатели), предоставляющие доступ к этим контейнерам как к массивам. Кроме того, STL позволяет сходным образом работать и с другими типами контейнеров, например, ассоциативными списками, стеками, очередями.

Используя шаблоны, можно писать обобщённые алгоритмы, способные работать с любыми контейнерами или последовательностями, определяемыми итераторами.

Так же, как и в Си, возможности библиотек активизируются использованием директивы #include для включения стандартных файлов. Всего в стандарте Си++ определено 50 таких файлов.

STL до включения в стандарт Си++ была сторонней разработкой, в начале — фирмы HP, а затем SGI. Стандарт языка не называет её «STL», так как эта библиотека стала неотъемлемой частью языка, однако многие люди до сих пор используют это название, чтобы отличать её от остальной части стандартной библиотеки (потоки ввода/вывода (iostream), подраздел Си и др.).

Проект под названием STLport[2], основанный на SGI STL, осуществляет постоянное обновление STL, IOstream и строковых классов. Некоторые другие проекты также занимаются разработкой частных применений стандартной библиотеки для различных конструкторских задач. Каждый производитель компиляторов Си++ обязательно поставляет какую-либо реализацию этой библиотеки, так как она является очень важной частью стандарта и широко используется.

[править]
Объектно-ориентированные особенности языка

Си++ добавляет к Си объектно-ориентированные возможности. Он вводит классы, которые обеспечивают три самых важных свойства ООП: инкапсуляцию, наследование и полиморфизм.

Существует два значения слова класс. В широком смысле класс — это пользовательский тип, объявленный с использованием одного из ключевых слов class, struct или union. В узком смысле класс — это пользовательский тип, объявленный с использованием ключевого слова class.

[править]
Инкапсуляция

Основным способом организации информации в Си++ являются классы. В отличие от типа структура (struct) языка Си, которая может состоять только из полей и вложенных типов, класс (class) Си++ может состоять из полей, вложенных типов и функций-членов (member functions). Члены класса бывают публичными (открытыми, public), защищёнными (protected) и собственными (закрытыми, приватными, private). В Си++ тип структура аналогичен типу класс, отличие в том, что по умолчанию члены и базовые классы у структуры публичные, а у класса — собственные.

С открытыми (публичными) членами класса можно делать снаружи класса всё, что угодно. К закрытым (приватным) членам нельзя обращаться извне класса, чтобы не нарушить целостность данных класса. Попытка такого обращения вызовет ошибку компиляции. К таким членам могут обращаться только функции-члены класса (а также так называемые функции-друзья и функции-члены классов-друзей; о понятии друзей в C++ см. ниже). Помимо открытых и закрытых членов класса, могут быть ещё и защищённые — это члены, доступные содержащему их классу, его друзьям, а также производным от него классам. Такая защита членов называется инкапсуляцией.

Используя инкапсуляцию, автор класса может защитить свои данные от некорректного использования. Кроме того, она задумывалась для облегчения совместной разработки классов. Имелось в виду, что при изменении способа хранения данных, если они объявлены как защищённые или собственные, не требуется соответствующих изменений в классах, которые используют изменённый класс. Например, если в старой версии класса данные хранились в виде линейного списка, а в новой версии — в виде дерева, те классы, которые были написаны до изменения формата хранения данных, переписывать не потребуется, если данные были приватными или защищёнными (в последнем случае — если использующие классы не были классами-наследниками), так как ни один из них этих классов не мог бы напрямую обращаться к данным, а только через стандартные функции, которые в новой версии должны уже корректно работать с новым форматом данных. Даже оператор доступа operator [] может быть определён как такая стандартная функция.

Используя инкапсуляцию, структуру Array из предыдущего раздела можно переписать следующим образом:
class Array {
public:
    void Alloc(int new_len);
    void Free();
    inline double Elem(int i);
    inline void ChangeElem(int i, double x);
protected:
    int len;
    double* val;
};
 
void Array::Alloc(int new_len)
    {if (len>0) Free(); len=new_len; val=new double[new_len];}
void Array::Free() {delete [] val; len=0;}
inline double Array::Elem(int i)
    {assert(i>=0 && i<len ); return val[i];}
inline void Array::ChangeElem(int i, double x)
    {assert(i>=0 && i<len); val[i]=x;}

И далее
Array a;
a.Alloc(10);
a.ChangeElem(3, 2.78);
double b = a.Elem(3);
a.Free();

Здесь массив a имеет 4 публичных функции-члена и 2 защищённых поля. Описатель inline означает подсказку компилятору, что вместо вызова функции её код следует подставить в точку вызова, чем иногда можно достичь большей эффективности.

[править]
Описание функций в теле класса

В теле класса можно указать только заголовок функции, а можно описать всю функцию. Во втором случае она считается встраиваемой (inline), например:
class Array {
public:
    void Alloc(int _len)
        {if (len==0) Free(); len=_len; val=new double[len];}

и так далее.

[править]
Конструкторы и деструкторы

Однако в приведённом примере не решена важная проблема: функции Alloc и Free по-прежнему надо вызывать вручную. Другая проблема данного примера — опасность оператора присваивания.

Для решения этих проблем в язык были введены конструкторы и деструкторы. Конструктор вызывается каждый раз, когда создаётся объект данного типа; деструктор — при уничтожении. При преобразованиях типов с участием экземпляров классов тоже вызываются конструкторы и деструкторы.

С конструкторами и деструктором класс выглядит так:
class Array {
public:
    Array() : len(0), val(NULL) {}
    Array(int _len) : len(_len) {val = new double[_len];}
    Array(const Array& a);
    ~Array() { Free(); }
    inline double Elem(int i);
    inline void ChangeElem(int i, double x);
protected:
    void Alloc(int _len);
    void Free();
    int len;
    double* val;
};
 
Array::Array(const Array& a) : len(a.len)
{
    val = new double[len];
    for (int i=0; i<len; i++)
        val[i] = a.val[i];
}

Здесь Array::Array — конструктор, а Array::~Array — деструктор. Конструктор копирования (copy constructor) Array::Array(const Array&) вызывается при создании нового объекта, являющегося копией уже существующего объекта. Теперь объект класса Array нельзя испортить: как бы мы его ни создавали, что бы мы ни делали, его значение будет хорошим, потому что конструктор вызывается автоматически. Все опасные операции с указателями спрятаны в закрытые функции.
Array a(5); // вызывается Array::Array(int)
Array b;    // вызывается Array::Array()
Array c(a); // вызывается Array::Array(const Array&)
Array d=a;  // то же самое
b=c;        // происходит вызов оператора =
            // если он не определён (как в данном случае), то вызывается оператор присваивания по умолчанию, который
            // осуществляет копирование базовых подобъектов и почленное копирование нестатических членов-данных.
            // как правило конструктор копий и оператор присваивания переопределяются попарно

Оператор new тоже вызывает конструкторы, а delete — деструкторы.

По умолчанию, каждый класс имеет неявно объявленные конструктор без параметров, копирующий конструктор, копирующий оператор присваивания и деструктор.

Класс может иметь сколько угодно конструкторов (с разными наборами параметров), но только один деструктор (без параметров).

[править]
Другие возможности функций-членов

Функции-члены могут быть и операциями:
class Array {

    inline double &operator[] (int n)
    {
         return val[n];
    }

И далее
Array a(10);

double b = a[5];

Функции-члены (и только они) могут иметь описатель const
class Array {

    inline double operator[] (int n) const;

Такие функции не имеют права изменять поля класса (кроме полей, определённых как mutable). Если они пытаются это сделать, компилятор должен выдать сообщение об ошибке.

[править]
Наследование

Для создания классов с добавленной функциональностью вводят наследование. Класс-наследник имеет поля и функции-члены базового класса, но не имеет права обращаться к собственным (private) полям и функциям базового класса. В этом и заключается разница между собственными и защищёнными членами.

Класс-наследник может добавлять свои поля и функции или переопределять функции базового класса.

По умолчанию, конструктор наследника без параметров вызывает конструктор базового класса, а затем конструкторы нестатических членов-данных, являющихся экземплярами классов. Деструктор работает в обратном порядке. Другие конструкторы приходится определять каждый раз заново. К счастью, это можно сделать вызовом конструктора базового класса.
class ArrayWithAdd : public Array {
    ArrayWithAdd(int n) : Array(n) {}
    ArrayWithAdd() : Array() {}
    ArrayWithAdd(const Array& a) : Array(a) {}
    void Add(const Array& a);
};

Наследник — это больше чем базовый класс, поэтому, если наследование открытое, то он может использоваться везде, где используется базовый класс, но не наоборот.

Наследование бывает публичным, защищённым и собственным. При публичном наследовании, публичные и защищённые члены базового класса сохраняют свой статус, а к собственным не могут обращаться даже функции-члены наследника. Защищённое наследование отличается тем, что при нём публичные члены базового класса являются защищёнными членами наследника. При собственном наследовании все члены базового класса становятся собственными членами класса-наследника. Таким образом, пользователь производного класса не может обращаться к членам базового класса, даже если они объявлены как публичные. Класс-наследник делает их собственными с помощью собственного наследования. Как правило, публичное наследование встречается значительно чаще других.

Класс может быть наследником нескольких классов. Это называется множественным наследованием. Такой класс обладает полями и функциями-членами всех его предков. Например, класс FlyingCat (ЛетающийКот) может быть наследником классов Cat (Кот) и FlyingAnimal (ЛетающееЖивотное)
class Cat {
    …
    void Purr();
    …
};
class FlyingAnimal {
    …
    void Fly();
    …
};
class FlyingCat : public Cat, public FlyingAnimal {
    …
    PurrAndFly() {Purr(); Fly();}
    …
};

[править]
Полиморфизм

Полиморфизмом в программировании называется переопределение наследником функций-членов базового класса, например
class Figure {
    …
    void Draw() const;
    …
};
 
class Square : public Figure {
    …
    void Draw() const;
    …
};
 
class Circle : public Figure {
    …
    void Draw() const;
    …
};

В этом примере, какая из функций будет вызвана — Circle::Draw(), Square::Draw() или Figure::Draw(), определяется во время компиляции. К примеру, если написать
Figure* x = new Circle(0,0,5);
x->Draw();

то будет вызвана Figure::Draw(), поскольку x — объект класса Figure. Такой полиморфизм называется статическим.

Но в C++ есть и динамический полиморфизм, когда вызываемая функция определяется во время выполнения. Для этого функции-члены должны быть виртуальными.
class Figure {
    …
    virtual void Draw() const;
    …
};
 
class Square : public Figure {
    …
    virtual void Draw() const;
    …
};
 
class Circle : public Figure {
    …
    virtual void Draw() const;
    …
};
 
Figure* figures[10];
figures[0] = new Square(1, 2, 10);
figures[1] = new Circle(3, 5, 8);

for (int i = 0; i < 10; i++)
    figures[i]->Draw();

В этом случае для каждого элемента будет вызвана Square::Draw() или Circle::Draw() в зависимости от вида фигуры.

Чисто виртуальной функцией называется функция-член, которая объявлена со спецификатором = 0:
class Figure {
    …
    virtual void Draw() const = 0;
);

Чисто виртуальная функция может быть оставлена без определения, кроме случая, когда требуется произвести её вызов. Абстрактным классом называется такой, у которого есть хотя бы одна чисто виртуальная функция-член. Объекты таких классов создавать запрещено. Абстрактные классы часто используются как интерфейсы.

[править]
Друзья

Функции-друзья — это функции, не являющиеся функциями-членами и тем не менее имеющие доступ к защищённым и собственным полям и функциям-членам класса. Они должны быть описаны в теле класса как friend. Например:
class Matrix {
    …
    friend Matrix Multiply(Matrix m1, Matrix m2);
    …
};
 
Matrix Multiply(Matrix m1, Matrix m2) {
    …
}

Здесь функция Multiply может обращаться к любым полям и функциям-членам класса Matrix.

Существуют также классы-друзья. Если класс A — друг класса B, то все его функции-члены могут обращаться к любым полям и функциям членам класса B. Например:
class Matrix {
    …
    friend class Vector;
    …
};

Однако в С++ не действует правило «друг моего друга — мой друг».

По стандарту C++03 вложенный класс не имеет прав доступа к закрытым членам объемлющего класса и не может быть объявлен его другом (последнее следует из определения термина друг как нечлена класса). Тем не менее, многие широко распространённые компиляторы нарушают оба эти правила (по всей видимости, ввиду совокупной странности этих правил).

[править]
Будущее развитие

Си++ продолжает развиваться, чтобы отвечать современным требованиям. Одна из групп, занимающихся языком Си++ в его современном виде и направляющих комитету по стандартизации Си++ советы по его улучшению — это Boost. Например, одно из направлений деятельности этой группы — совершенствование возможностей языка путём добавления в него особенностей метапрограммирования.

Стандарт Си++ не описывает способы именования объектов, некоторые детали обработки исключений и другие возможности, связанные с деталями реализации, что делает несовместимым объектный код, созданный различными компиляторами. Однако для этого третьими лицами создано множество стандартов для конкретных архитектур и операционных систем.

Тем не менее (по состоянию на время написания этой статьи) среди компиляторов Си++ всё ещё продолжается битва за полную реализацию стандарта Си++, особенно в области шаблонов — части языка, совсем недавно полностью разработанной комитетом стандартизации.

[править]
Ключевое слово export

Одной из точек преткновения в этом вопросе является ключевое слово export, используемое также и для разделения объявления и определения шаблонов.

Первым компилятором, поддерживающим export в шаблонах, стал Comeau C++ в начале 2003 года (спустя пять лет после выхода стандарта). В 2004 году бета-версия компилятора Borland C++ Builder X также начала его поддержку.

Оба этих компилятора основаны на внешнем интерфейсе EDG. Другие компиляторы, такие как Microsoft Visual C++ или GCC (GCC 3.4.4), вообще этого не поддерживают. Герб Саттер (англ.), секретарь комитета по стандартизации Си++, рекомендовал убрать export из будущих версий стандарта по причине серьёзных сложностей в полноценной реализации, однако впоследствии окончательным решением было решено его оставить.

Из списка других проблем, связанных с шаблонами, можно привести вопросы конструкций частичной специализации шаблонов, которые плохо поддерживались в течение многих лет после выхода стандарта Си++.

[править]
Си++ не включает в себя Си

Несмотря на то что большая часть кода Си будет справедлива и для Си++, Си++ не является надмножеством Си и не включает его в себя. Существует и такой верный для Си код, который неверен для Си++. Это отличает его от Объектного Си, ещё одного усовершенствования Си для ООП, как раз являющегося надмножеством Си.

Например, следующий фрагмент кода корректен с точки зрения Си, но некорректен с точки зрения Си++:
typedef struct mystr {
    int a;
    int b;
} mystr;

Дело в том, что в Си идентификаторы структур (теги структур), то есть идентификаторы, используемые при описании структуры в качестве имени структуры, являются сущностями отдельного вида, имеющими обособленное пространство имён, тогда как в Си++ идентификатор структуры представляет собой попросту её тип. Таким образом, в языке Си вышеприведённый фрагмент вводит структуру mystr и новый тип mystr, тогда как в Си++ этот же фрагмент будет воспринят как попытка дважды описать тип с именем mystr.

Другим источником несовместимости являются добавленные ключевые слова. Так, описание переменной
    int try;

является вполне корректным для Си, но заведомо ошибочным для Си++, поскольку слово try является в Си++ ключевым.

Существуют и другие различия. Например, Си++ не разрешает вызывать функцию main() внутри программы, в то время как в Си это действие правомерно. Кроме того, Си++ более строг в некоторых вопросах; например, он не допускает неявное приведение типов между несвязанными типами указателей и не разрешает использовать функции, которые ещё не объявлены.

Более того, код, верный для обоих языков, может давать разные результаты в зависимости от того, компилятором какого языка он оттранслирован. Например, на большинстве платформ следующая программа печатает «С», если компилируется компилятором Си, и «С++» — если компилятором Си++. Так происходит из-за того, что символьные константы в Си (например ‘a’) имеют тип int, а в Си++ — тип char, а размеры этих типов обычно различаются.
#include <stdio.h>
 
int main()
{
    printf(“%s\n”, (sizeof(‘a’) == sizeof(char)) ? “C++” : “C”);
    return 0;
}

[править]
Примеры программ на Си++

[править]
Пример № 1

Это пример программы, которая не делает ничего. Она начинает выполняться и немедленно завершается. Она состоит из основного потока: функции main(), которая обозначает точку начала выполнения программы на Си++.
int main()
{
    return 0;
}

Стандарт Си++ требует, чтобы функция main() возвращала тип int. Программа, которая имеет другой тип возвращаемого значения функции main(), не соответствует стандарту Си++.

Стандарт не говорит о том, что на самом деле означает возвращаемое значение функции main(). Традиционно оно интерпретируется как код возврата программы. Стандарт гарантирует, что возвращение 0 из функции main() показывает, что программа была завершена успешно.

Завершение программы на Си++ с ошибкой традиционно обозначается путём возврата ненулевого значения.

[править]
Пример № 2

Эта программа также ничего не делает, но более лаконична.
int main(){}

В Си++, если выполнение программы доходит до конца функции main(), то это эквивалентно return 0;. Это неверно для любой другой функции кроме main().

[править]
Пример № 3

Это пример программы Hello World, которая выводит это знаменитое сообщение, используя стандартную библиотеку, и завершается.
#include <iostream> // это необходимо для std::cout и std::endl
 
int main()
{
    std::cout << “Hello, world!” << std::endl;
}

[править]
Пример № 4

Современный Си++ позволяет решать простым способом и более сложные задачи. Этот пример демонстрирует кроме всего прочего использование контейнеров стандартной библиотеки шаблонов (STL).
#include <iostream>   // для использования std::cout
#include <vector>     // дл