История языка
Язык возник в начале 1980-х годов, когда сотрудник фирмы Bell Laboratories Бьёрн Страуструп придумал ряд усовершенствований к языку C под собственные нужды. До начала официальной стандартизации язык развивался в основном силами Страуструпа в ответ на запросы программистского сообщества. В 1998 году был ратифицирован международный стандарт языка C++: ISO/IEC 14882:1998 «Standard for the C++ Programming Language»; после принятия технических исправлений к стандарту в 2003 году — нынешняя версия этого стандарта — ISO/IEC 14882:2003.
Сейчас существует множество сред программирования, которые поддерживают этот язык, такие как: NOKIA Qt, Microsoft Visual Studio, Embarcadero RAD Studio и др.
Обзор языка
Стандарт C++ на 2003 год состоит из двух основных частей: описание ядра языка и описание стандартной библиотеки.
Кроме того, существует огромное количество библиотек C++, не входящих в стандарт. В программах на C++ можно использовать многие библиотеки C.
С++ поддерживает, как комментарии в стиле C
/*
это комментарий, который может состоять
из нескольких строчек
*/
, так и однострочные
// вся оставшаяся часть строки является комментарием
, где // обозначает начало комментария, а ближайший последующий символ новой строки, который не предварён символом \, считается окончанием комментария.
В C++ доступны следующие встроенные типы:
Символьные: char, wchar_t.
Целочисленные знаковые: signed char, short int, int, long int.
Целочисленные беззнаковые: unsigned char, unsigned short int, unsigned int, unsigned long int.
С плавающей точкой: float, double, long double.
Логический: bool, имеющий значения true и false.
Операции сравнения возвращают тип bool. Выражения в скобках после if, while приводятся к типу bool
Функции могут принимать аргументы по ссылке. Например, функция void f(int &x) {x=3;} присваивает своему аргументу значение 3. Функции также могут возвращать результат по ссылке, и ссылки могут быть вне всякой связи с функциями. Например, {double &b=a[3]; b=sin(b);} эквивалентно a[3]=sin(a[3]);.
При программировании ссылки в определённой степени сходны с указателями, со следующими особенностями:
перед использованием ссылка должна быть инициализирована;
ссылка пожизненно указывает на один и тот же адрес;
в выражении ссылка обозначает непосредственно тот объект или ту функцию, на которую она указывает, обращение же к объекту или функции через указатель требует разыменование указателя.
Концептуально ссылка — другое имя переменной или функции, другое название одного и того же адреса, существует лишь только в тексте программы, заменяемое адресом при компиляции; а указатель — переменная, хранящее адрес, к которому обращаются.
C++, в отличие от C, имеет объектно-ориентированные возможности. Он вводит классы, которые обеспечивают три самых важных свойства ООП: инкапсуляцию, наследование и полиморфизм.
В C++ под классом (class) подразумевается пользовательский тип, объявленный с использованием одного из ключевых слов class, struct или union, под структурой (structure) подразумевается класс, определённый через ключевое слово struct, и под объединением (union) подразумевается класс, определённый через ключевое слово union.
В C++ при наследовании одного класса от другого наследуется реализация класса, плюс класс-наследник может добавлять свои поля и функции или переопределять функции базового класса.
Конструктор наследника вызывает конструкторы базовых классов, а затем конструкторы нестатических членов-данных, являющихся экземплярами классов. Деструктор работает в обратном порядке.
Наследование бывает публичным, защищённым и закрытым (то есть закрытого типа), как показано ниже в таблице 1.1:
Таблица 1. Виды наследования языка С++
Доступ члена базового класса/режим наследования |
private-член |
protected-член |
public-член |
private-наследование |
недоступен |
private |
private |
protected-наследование |
недоступен |
protected |
protected |
public-наследование |
недоступен |
protected |
public |
Наследник — это больше чем базовый класс, поэтому, если наследование открытое, то он может использоваться везде, где используется базовый класс, но не наоборот.
Полиморфизмом в программировании называется переопределение наследником функций-членов базового класса, например:
class Figure
{
...
void Draw() const;
...
};
class Square : public Figure
{
...
void Draw() const;
...
};
class Circle : public Figure
{
...
void Draw() const;
...
};
Какая именно из функций будет вызвана — Figure::Draw(), Square::Draw() или Circle::Draw() — определяется во время компиляции. Например:
Circle *c = new Circle(0,0,5);
Figure *f = c; // Всё ok: Figure — базовый класс для Circle
c->Draw();
f->Draw(); // Указатели друг другу равны, но для f будет вызвана другая функция, чем для c.
Несмотря на то, что оба указателя указывают на один и тот же объект класса Circle, для c будет вызвана Circle::Draw(), а для f — Figure::Draw(), поскольку f — указатель на объект класса Figure.
Основным способом организации информации в C++ являются классы. В отличие от структуры (struct) языка C, которая может состоять только из полей и вложенных типов, класс (class) C++ может состоять из полей, вложенных типов и функций-членов (member functions). Инкапсуляция в С++ реализуется через указание уровня доступа к членам класса: они бывают публичными (открытыми, public), защищёнными (protected) и собственными (закрытыми, приватными, private). В C++ структуры формально отличаются от классов лишь тем, что по умолчанию члены и базовые классы у структуры публичные, а у класса — собственные.
Таблица 2. Виды доступа к классам
Доступ |
private |
protected |
public |
Сам класс |
да |
да |
да |
Друзья |
да |
да |
да |
Наследники |
нет |
да |
да |
Извне |
нет |
нет |
да |
Проверка доступа происходит во время компиляции, попытка обращения к недоступному члену класса вызовет ошибку компиляции.
В классах всегда есть специальные функции — конструкторы и деструкторы, которые могут быть объявлены явно или неявно.
Конструктор вызывается для инициализации объекта (соответствующего типа) при его создании, а деструктор — для уничтожения объекта.
Конструкторы обозначаются как одноимённые классу функции (например, Array::Array), деструкторы — как имя класса, предварённое тильдой (например, Array::~Array). Для конструкторов и деструкторов нельзя указывать тип возврата. Деструктор нельзя объявлять как принимающий аргументы. Класс может иметь сколько угодно конструкторов (с разными наборами параметров), в том числе шаблонных, и только один деструктор.