C++

Материал из Энциклопедия о программировании
Перейти к: навигация, поиск
C++
Семантикамультипарадигмальный (объектно-ориентированное, обобщённое, процедурное, метапрограммирование)
Классобъектно-ориентированный, мультипарадигмальный, процедурный, функционального программирования, обобщённого программирования, ЯП, free-form и компилируемый
Тип исполнениякомпилируемый
Появл.1983 г.
АвторБьёрн Страуструп
Расшир. файлов.cc, .cpp, .cxx, .c, .c++, .h, .hpp, .hh, .hxx или .h++
Сист. типовстатич.
Основн. реализацииGNU C++, Microsoft Visual C++, Intel C++ compiler, Open64 C++ Compiler, Clang, Comeau C/C++, Embarcadero C++ Builder, Watcom C++ compiler, Digital Mars C++, Oracle Solaris Studio C++ compiler, Turbo C++
ДиалектыISO/IEC 14882 C++
Испытал влияниеAda, ALGOL 68, C, CLU, ML, Mesa, Modula-2, Simula, Smalltalk
Сайтisocpp.org

C++ (полн. C plus plus, сокр. Cpp; трансл.: Си++, полн. Си плюс плюс, сокр. Спп) — компилируемый, строго статически типизированный ЯП общ. назнач.

Возможности

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

C++ сочетает св-ва как высоко. ур., так и низк. ур. ЯП.

Отличия от C

В сравнении с его предшеств., C, C++ наибольшее внимание уделено поддержке ООП и обобщ. прог-ния.

Популярность

C++ широко используется для разработки различного ПО, являясь одним из самых популярных языков программирования. Область его применения включает создание операционных систем, разнообразных прикладных программ, драйверов устройств, приложений для встраиваемых систем, высокопроизводительных серверов, а также развлекательных приложений (игр). Существует множество реализаций языка C++, как бесплатных, так и коммерческих и для различных платформ. Напр., на платформе x86 это GCC, Visual C++, Intel C++ Compiler, Embarcadero (Borland) C++ Builder и др. C++ оказал огромное влияние на др. ЯП, в 1-ую очередь на Java и C#.

Синтаксис C++

Синтаксис ЯП C++ унаследован от ЯП C. Одним из принципов разработки было сохранение совместимости с C. Тем не менее, C++ не является в строгом смысле надмножеством C. Множество программ, которые могут одинаково успешно транслироваться как компиляторами C, так и компиляторами C++, довольно велико, но не включает все возможные программы на C.

Особенности

Особенности и основные моменты C++:

  • Си-подобный синтаксис.
  • Чувствительность к регистру. Например, NULL и null это совсем разные идентификаторы.
  • Булева логика в C++ такова, что только 0 считается false, все остальные числа это true.
  • Наследование от классов происходит с помощью символа двоеточия (:), так же как и в C#.
  • В отличие от более новых Java и C#, в C++ разрешено множественное наследование. В этом случае названия классов записываются через запятую.
  • Сборка из исходного кода происходит в несколько этапов в след. послед-ти: препроцессор, компилятор, линкер (линковщик, сборщик).

Большой спектр символов для операторов

Язык выполнен в старом стиле языка C, который был популярен, когда языки программирования высокого уровня ещё толком не сформировались, а существующие языки программирования были больше похожи на какой-нибудь Assembler. В нём (в C++) в качестве операторов присутствуют самые различные символы: звёздочки (указатели), амперсанды (ссылки), стрелочки (обращение к элементам класса через динамический объект), тильды (деструкторы), двоеточия (модификаторы доступа) и т. д. Тут так не получится всё быстро с ходу понять, как в тех же Java и C#, где почти всё написано полноценными человеческими словами.

Высочайшая производительность

По сравнению с выполняемыми на виртуальных машинах и имеющими своих сборщиков мусора языков программирования (Java и C#), C++ сложнее для понимания, но именно он гарантирует максимальную производительность, что заставляет до сих пор (21 век) использовать его в высоконагруженных приложениях, напр., в компьютерных играх.

Различные вариации языка

В зависимости от используемого компилятора, ЯП C++ может существенно изменяться. Этот помимо регулярно выпускаемых непосредственно комиссией по стандартизации официальных изменений стандартов языка. Таким образом, можно сказать, что ЯП C++ имеет множество незадокументированных диалектов. Зачастую эти диалекты языка никак не называются. Обычно это просто компилятор, который поддерживает те или иные дополнения функционала языка. Например, в собственном компиляторе Qt используется своя разновидность языка C++, которая поддерживает дополнительный функционал, в частности тот самый сборщик мусора, а в компиляторе C++ от Makrosoft имеется своя реализация маршалинга.

Советы

Работая в C++ при создании переменных любых типов, в т.ч. и простых, всегда задавайте/устанавливайте им значения по-умолчанию, иначе при попытке обратиться к ним возникают ошибки, т.к. состояние неопределённо. Такие ошибки тяжело отслеживать так как программа просто падает и не о чём не говорит. Какие значения по-умолчанию использовать? Для строковых переменных лучше всего подходит пустая строка — "", для целочисленного типа — значение 0 или «минус один» (-1).

Основные отличия C++

Обращение после создания

В отличие от всяких относительно новомодных интерпретируемых PHP, JavaScript и прочих, в языке C++, как и во многих других компилируемых языках, по старинке (как и в C), для вызова функции необходимо её сперва определить или описать прототип этой функции. Также и с переменными и обращениям к ним.

ООП

Главным отличием C++ от C явл. именно поддержка полноценного ООП.

Обзор языка

Примеры кода на C++ с описаниями, примерами и пояснениями:

Препроцессор

Примеры синтаксиса и определения директив препроцессора:

Директивы препроцессора
Пример синтаксисаОписаниеДополнение
#include <iostream> Подключение заголовочного файла iostream (ввода/вывода потоков) C++. Подключение в стандартном стиле, т.е. без расширения у заголовочного файла, стандартной библиотеки языка.
#pragma once Создание правила при помощи директивы препроцессора #pragma. Все идущие после этой записи директивы #include будут подключать файлы к текущему файлу только один раз.
#define SQR(x) ((x)*(x)) Создание макроса (функции) при помощи директивы препроцессора #define. В аргументы производится грубая подстановка, поэтому в теле функции для соблюдения правил приоритетов операций все переменные в скобках. Макросы препроцессора не имеют возвращаемый тип и вообще типы в таких функциях не пишутся.

Пространства имен

Пространства имен
Код Описание Тема, раздел
using namespace std; Включение экспортируемых имен из пространства имён std (стандартной библиотеки, std — standart) в глобальное пространство имён. Широко используется в учебных целях, в продакшине считается дурным тоном, ибо пространств имен полно и приходится обращаться к разным.
using std::cout; Экспорт в текущее пространство имён только сущности cout из пространства имён std (стандартной библиотеки языка).
std::cin; Использование cin из пространства имён std. Именно такой подход является нормальным, т.к. в продакшине, в отличии от обучения, не используется конструкция using namespace.
namespace Space {
int i;
float r (int);
}
Создание именованного пространства имен Space. В нём можно писать всё, что угодно. При повторном использовании namespace Space {…} будет происходить не переопределение этого пространства имен, а его дополнение. При этом повторно инициализировать уже ранее созданные идентификаторы нельзя, но объявлять можно. Пространства имен
Space::i=7; Получение доступа к переменной i из пространства имен Space.Получение доступа к переменной из другого пространства имен.
namespace S=Space; Создание пространства имен S и присвоение ему пространства Space, таким образом теперь S и Space — синонимы. Присвоение пространств имен.
float Space::r(int p) {…} Инициализация функции r, прототип которой был объявлен в пространстве имен Space. То есть эта функция находится в пространстве имен Space. Инициализация функции из именованного пространства имен.
using namespace Space; Объявление использования по-умолчанию пространства имен Space. Писать данную строку можно в любом месте кода. После написания считается, что все объекты берутся оттуда, если их нет в глобальном пространстве имен.
using std::cout; Использование только сущности cout из пространства имен std, в то время как остальные объекты из std по-умолчанию не будут браться оттуда и это придется указывать явно, в отличие от cout.
std::int x; Создание переменной x в пространстве имен std, i.e. переменной x, принадлежащей пространству имен std. Пространства имен

Приведение типов

Явное приведение типов
Пример синтаксисаОпределение действияОписание примера
Небезопасное приведение типа из C
(int)a;Явное, нежелательное и опасное в C++, приведение типа, наследованное из C.Переменная a приводится к типу integer, т.е. в левую часть выражения вернётся приведённое значение, а тип и значение переменной a остаются неизменными.
(int *)vp;Явное приведение типа указателя.Указатель vp приводится к указателю на тип integer, то есть в левую часть выражения вернётся приведённое значение, при этом указатель vp остаётся неизменным.
Безопасное приведение типа, введённое в C++
double(x);Явное безопасное и рекомендуемое приведение типа переменной, введённое именно в C++.Переменная x приводится к типу double, т.е. в левую часть выражения вернётся приведённое значение, а тип и значение переменной x остаются неизменными.
Небезопасное приведение типа конструкцией cast
static_cast<type>(x);Явное небезопасное статическое приведение типа.
dynamic_cast<type*>(x);Явное небезопасное динамическое приведение типа.

Классы

Примеры объявления и создания классов
СинтаксисОписаниеНазвание
class SomeClass; Объявление класса SomeClass без его инициализации. Декларация класса
class NameClass {}; Объявление и создание класса с именем NameClass. Декларация и реализация класса
class Foo {
public:
  int x, y = 2, z;
protected:
  float a;
private:
  void f() {}
};
Создание класса Foo и создание в нём полей и методов (переменных и функций) с типами доступа public, protected и private. Создание класса и его идентификаторов с различными уровнями доступа.
class B : public A {…}; Создание класса B, что публично наследуется от класса A. Наследование от класса
class D : public A, private B, protected C {…}; Множественное наследование классов.
class Foo {} bar, bar2 = bar, bar3(bar2); Создание класса Foo и создание его объектов, а также их копирующая и прямая инициализации. Всё в одном стейтменте.

Интерфейсы

В C++, в отл. от более поздних Java и C#, нет явного определения интерфейсов, поэтому класс, в котором все функции абстрактные, условно называется интерфейсом. По определённой договорённости (по правилам хорошего тона написания текста программы (кода)), для быстрой идентификации и большей наглядности, перед названием интерфейса ставится большая буква "I" (от слова "Interface"), но это не обязательно с точки зрения компилятора, т.к. это обозначение только для читателей кода.

Объекты/экземпляры классов

Переменные, имеющие тип класса, называются объектами/экземплярами класса. Все объекты независимы и индивидуальны.

В отлич. от Java и C#, где объекты классов могут создаваться только динамически — в управляемой куче, в C++ объекты классов помимо динамического создания можно создавать и статически — прямо в стеке; т.е., в отлич. от вышеуказанных ЯП, в C++ имеется не 1, а целых 2 типа объектов/экземпляров классов — статические, что размещаются в стеке, и динамические, что помещаются в кучу.

Маленькие локальные временные объекты удобнее создавать статически (в стеке), т.к. это происходит быстрее, чем динамическое выделение памяти в управляемой куче.

Внутри класса в C++ нельзя объявлять объект этого же класса.

КодОписаниеНазвание
Статическое создание объектов (в стеке)
Cls x = Cls(3, 5); Создание статического объекта x класса Cls, и передача в соотв. конструктор класса 2-ух параметров — 3 и 5.

Особенности:

  • Если передавать в конструктор класса нечего, то круглые скобки всё равно ставятся. Писать без круглых скобок после имени класса нельзя, как это можно делать при динамическом создании объекта.
  • Это единственный вид синтаксиса, с помощью которого можно задать значение по-умолчанию для аргумента функции/метода, что явл. статическим объектом класса.
Длинный синтаксис создания статического объекта класса.
Cls x(5, 'a', 2.5); Создание статического объекта класса Cls, и передача в соотв. конструктор класса параметров.

Особенности:

  • Без передачи парам. будет выглядеть так: Cls x();, или в укороч. варианте без скобок: Cls x;.
  • Таким вариантом синтаксиса нельзя задать значение по-умолчанию для аргумента функции/метода, что явл. статическим объектом класса.
Статический объект класса с передачей аргументов в перегруженный конструктор класса.
SomeClass someObj;Укороченный синтаксис созд. статич. объекта класса SomeClass.Укороч. запись созд. статич. объекта.
SomeClass some = 5; Создание статического объекта some класса SomeClass, и через оператор присваивания (=) передача аргумента перегруженному конструктору класса.

Особенности:

  • Такой синтаксис запрещен, если у конструктора был указан спецификатор explicit.
Статический объект класса с передачей аргументов в перегруженный конструктор класса объекта через оператор присвоения (=).
Динамич. создание объектов (в управляемой куче)
C *x = new C(2, 8);Создание динамич. объекта класса C, передача параметров в соотв. конструктор, и занесение объекта в указатель x.Динамический объект класса.
Cls *x = new Cls;Укороченный вариант синтаксиса создания динамич. объекта класса Cls и занесение его в указатель x.Динамический объект класса. Укороченная запись.

Доступ к элементам объектов классов

В C++, в отличие от Java и C# и пр., имеется несколько операторов доступа к элементам объектов/экземпляров классов, которые применяются в зависимости от типа объекта — статического (прямого доступа) или динамического (доступа через указатель).

  • При создании статического объекта, для доступа к его методам и свойствам, используется операция прямого обращения — «.» (символ точки). Точка — оператор получения доступа к доступным полям и методам статического объекта.
  • Если же память для объекта выделяется посредством указателя, то для доступа к его методам и свойствам используется оператор косвенного обращения — «->» (стрелочка).
Пример синтаксиса Описание действия Определение
y.get_city(foo); Вызов метода get_city статически созданного объекта y. Обращение к полям и методам статически созданного объекта.
(*z).set_pos(num); Вызов метода set_pos через указатель динамически созданного объекта z. Через оператор выставления повышенного приоритета выполнения (()), сперва через разыменование (*) по хранимому в указателе адресу происходит доступ к самому объекту, а затем через оператор получения доступа к членам объекта (.) происходит доступ к его методу set_pos, через оператор вызова функции/метода (()) происходит вызов метода и передача ему параметра num. Оператор повышенного приоритета выполнения (()) нужен, потому что у оператора доступа к членам объекта (.) более высокий приоритет, чем у разыменования (*). Обращение через указатель к полям и методам динамически созданного объекта.
x->set_name(name); Обращение к методу set_name динамически созданного объекта через указатель на него x. Косвенное, через указатель, обращение к полям и методам динамически созданного объекта.

Ссылки и указатели

Ссылки и указатели
Код Описание Название
int & d = t; Создание ссылки d типа int, которая ссылается на переменную t типа int. Теперь t и d ссылаются на одно значение в памяти к которому можно получить доступ по обоим переменным.
int &h=vln[i]; Создание ссылки h на переменную vln[i]. Ссылка h ссылается не на весь массив, а только на конкретный его элемент i. Ссылки
int (*pn)(short)=fn; Создание ссылки pn на функцию fn, функция принимает переменную типа short и возвращает тип int. Ссылка на функцию
int (*pn[])(short)={fn, fy}; Создание массива ссылок на функции. Нулевой элемент массива ссылкается на функцию fn, первый элемент массива ссылается на функцию fy. Массив ссылок на функции
&b; Получение адреса значения переменной b. Взятие адреса
int *p; Объявление указателя p, который ссылается на тип int. Указатели
int *p=&s; Создание указателя p на переменную s типа int. Указатель ссылается только на адрес, а не на переменную! Поэтому в переменную указателя заносится АДРЕС переменной s при помощи знака амперсанта (&) Указатели
int *a = new int; Создание указателя (ссылки) a, которая может ссылаться на объекты типа int. Указатели
int *b = new int(5); Создание указателя b, который ссылается на объект типа int со значением 5.
int *p=&s, *p2; Создание двух указателей, один из которых ссылается на переменную s. Знак звездочки (указателя) привязывается не к типу, а к имени! Поэтому её всегда надо ставить перед именем переменной дабы явно указать, что это указатель! Указатели
p2=&s; Ранее продикларированному указаетелю p2 присваиваем адрес переменной s (все типы одинаковые!), только адрес! Когда укзатель используется без звездочки, то указателем является тип. Когда используем адрес указателя то пишем просто имя переменной указателя. Когда же используем значение указателя, лежащее по адресу указателя, то используем знак звездочки перед именем переменной указателя.
*p2=8; Ранее продикларированному указаетелю p2 присваиваем значение 8 (все типы одинаковые!), только значение! Использование звездочки называется разодрисацией. Исплользование имени переменной указателя со звездочкой ссылается на значение (не на адрес!) в этом смысле указатель применяется как ссылка. Для того, чтобы работать со значениями указателя (как в примере), надо чтобы у указателя был адрес! То есть надо сделать так p2=&someVar;. Мнемочиеское правило int * p то, что остается на то и ссылаемся, либо на значение либо на адрес: *p — значение, p — адрес.
p2=p3; Присвоение указателя p3 указателю p2. Для такого они должны иметь одинаковые типы данных. Теперь указатель p2 ссылается на такой же объект, на который ссылается и указатель p3. Присваивание указателей
*p2=*p3; Присвоение значения одного указателя значению другого.
int q[15], *p=q; p+1; создания массива q и указателя на этот массив p. Далее к указателю (к адресу) прибавляем 1 и к адресу на который ссылается p прибавляется количество байт содержимых в типе int (4 байта) так как p и q типа int. while(*p) {cout<<*p++;}
int q[15]={}; *(q+2); Адрес массива (нулевого элемента массива) увеличиваем на два, то есть два раза взять по количеству байт типа указателя q (int). Таким образом q уже будет ссылаться на другую область памяти. Не на нулевой элемент, а на второй. Далее операция разодресации (*), то есть берём значение находящиеся по этому адресу, а не адрес.
int *p = nullptr; Создание указателя p типа int, который ни на что не ссылается, то есть Null pointer.
int *p = new int; Создаем указатель p и с помощью оператора new выделяем память для типа int (4 байта). Таким образом у нас есть указатель на область памяти, которую можно заполнить. Компилятор выделяет память для хранения указателя, а сам адрес получается динамически (динамически = во время выполнения программы).
int *p = new int(128); Создаем указатель p и с помощью оператора new выделяем память для типа int (4 байта). Далее вносим в эту область памяти значение 128 типа int.
int *p = new int[5]; Динамическое создание массива типа int состоящего из пяти элементов. Создаем указатель p и с помощью new выделяем память для пяти переменных типа int (4 байта). Возвращается указатель на самое начало массива (на индекс 0). Размерность массива может быть переменной (не константой) так как он динамический. Именем массива является p.
int **p=(int **) new int[size][5]; Создание двумерного динамического массива. Переменной может быть только первое значение размерности, все последующие — константы. Создается указатель на указатель p. New возвращает указатель на первый элемент массива и его явно преобразовываем в указатель на указатель типа int. Количество звездочек в обоих случаях прямо зависит от размерности создаваемого динамического массива.
int **p=new *int[size]; Создание указателя на указатель с названием p, в него вносим создаваемый при помощи new указатель на массив указателей. Создание двумерного массива указателей на указатели.
for(int i=0; i<size; i++) p[i]=new int[count]; Инициализация двумерного динамического массива. В указатель p[i] заносим указатель на нулевой элемент массива интов размером в count элементов.

Функции и методы

Функции и методы
СинтаксисОпределениеДополнениеОписание
bool func(); Объявление функции func без её инициализации. Она возвращает тип bool и не принимает аргументов, имеет название func. Можно сначала просто объявить функцию (создать прототип), а инициализировать её (создать тело) позже. Обычно после объявления функции её сразу же инициализируют. Объявление без инициализации функции без параметров
int func(int x, float); Объявление функции func без её инициализации. Она возвращает тип int, имеет название func. Принимает 2 аргумента: первый: название x, тип int; второй: без названия, тип float. В самих функциях названия переменных в аргументах не обязательны, но они требуются, чтобы получить доступ к этим переменным и поэтому всегда используются. Объявление без инициализации функции с параметрами
void func(char* = 0); Объявление функции func без её инициализации. Функция ничего не возвращает (void), имеет название func. Принимает 1 аргумент без названия типа char* (указатель на тип char) со значением по-умолчанию 0. Если в функцию передается указатель и у этой переменной нет имени, то после знака звездочки (*) нужен хотя бы один пробел, иначе это будет интерпретироваться как операция умножения текущего значения на число. Объявление без инициализации функции с параметром-ссылкой
void f(int arr[]); Передача в функцию f массива arr любой размерности.
int bar(int x, const float y, int u[5], short &z) {return x;} Создание функции bar со след. аргументами: x типа int, константы y типа float (это значит лишь то, что эта переменная не будет изменяться внутри функции, принимать же она может и обычные переменные, и константы), массива u элементов типа int (его размерность значения здесь не играет, мы можем передать в функцию массив любой размерности), передаваемых по значению, и z типа short, передаваемый по ссылке. Возвращаемым значением является тип int. Возвращается переменная x типа int. Объявление функции, принимающей разные параметры и её инициализация.
void find(int *x) {…} Создание функции find, которая принимает переменную-указатель (*) x (это может быть как переменная, так и массив) типа int. Функция, принимающая в качестве параметра/аргумента указатель.
int* f(int a) {return &a;} создание функции f, которая принимает по значению переменную a типа int, и возвращает указатель на неё. Т.к. переменная типа int, то и указатель на адрес тоже тип int. В теле функции просто берём адрес переменной и возвращаем его. Т.к. переменная передана по значению, то при вызове функции будет создавать новая переменная int a и будет возвращаться уже её адрес, а не адрес переданной в функцию переменной. Функция возвращающая указатель на переменную типа int
fnc(5, x, y); Вызов функции fnc и передача ей в качестве аргументов числа 5, переменной x, и передача по ссылке переменной y. Передача по ссылке при вызове функции никак не обозначается, то, что она принимает переменную y по ссылке указывается в определении этой функции. При вызове функции мы просто указываем переменные или значения без всяких уточняющих знаков способа передач (по ссылке или по значению), все это задается в аргумент листе самой функции при её описании. Параметры по умолчанию можно не передавать. Вызов функции
float f(float x, float b = 0.0, int c = 0) {…} Создание функции с параметрами по-умолчанию. Аргументы b и c уже при объявлении имеют свою инициализацию — это параметры по-умолчанию. Параметры по-умолчанию всегда пишутся в конце всех параметров функции. Значения параметров по-умолчанию применяются, когда эти параметры в функцию явно не переданы. При вызове функции параметры по-умолчанию можно не передавать, в этом случае в эти переменные подставятся значения по-умолчанию. При вызове функции не указывать можно только последние параметры по-умолчанию, пропускать их нельзя, т.е. можно передать только b не передав c, но передать с, не передав b, не получится. Функция с параметрами по-умолчанию
void x(int z) {…}
int x(float z) {…}
создание функции x, принимающей переменную z типа int и её перегрузки принимающей переменную z типа float. Перегружающая функция должна иметь такое же название и быть в той же области видимости. Перегрузка функций различается по аргумент листу. Тип возвращаемого значения роли не играет. Перегрузка функций
float x(bool, float = 0.0, int c = 0);Создание прототипа (декларации) функции x без её определения.Прототип функции
virtual void information();Создание виртуальной функции.Виртуальная функция без реализации
virtual void info() = 0; Создание чисто виртуальной (абстрактной) функции (чисто виртуального метода). При наследовании класса с этой функцией её надо будет явно определить в дочернем классе. При этом такая функция будет являться виртуальной для каждого класса-наследника. Виртуальная абстрактная функция (чисто виртуальная функция) без реализации
void fn(void (*f)(int), int p) {f(p);} Функция fn принимает в качестве аргумента указатель f на др. функцию, и в своём теле через этот указатель вызывает функцию, на которую указывает указатель. Функция принимающая параметр указатель на др. функцию
const char* f() const throw() {} Метод f возвращает указатель на тип char, не изменяет состояние объекта и не выбрасывает исключений.

Конструкторы и деструкторы

Конструкторы и деструкторы
Синтаксис Определение Дополнение К чему относится
NameClass::NameClass(int x) {} Создание конструктора класса NameClass, который при создании объекта этого класса принимает значение x типа int. Имя конструктора аналогично имени класса. Конструктор класса
NameClass::~NameClass() {} Создание деструктора класса NameClass. Имя деструктора аналогично имени класса и конструктора, только в начале ставится знак тильды ~. Деструктор класса
CVec(float _x, float _y, float _z): x(_x), y(_y), z(_z) {} Создание конструктора класса CVec и его списка инициализации. Присвоение в списке инициализации переданного в конструктор значения _x в поле/свойство x класса CVec и т. д. Конструктор класса со списком инициализации

Структуры

Структуры
Синтаксис Определение Примеры
struct Bar {}; Создание структуры с именем Bar. struct Item { bool flag; };
struct {} foo; Создание безымянной структуры и объекта/переменной этой структуры с именем foo. struct { int f; } bar;

Объекты структур

СинтаксисОпределениеДополнениеК чему относится
NameStructure x; Создание объекта структуры NameStructure. Объекты структур

Массивы

Пример синтаксисаОпределениеНазвание
Обычный статический массив
float arr[10]; Декларация статического массива arr типа float с количеством ячеек 10. Обычный статический массив
char x[] = {'b','k','c'}; Декларация и инициализация одномерного статического массива с тремя элементами без явного указания размера массива, т.к. размер будет определяться автоматически по кол-ву элементов в фигурных скобках.
int a[5] = {1, 5, 8}; Декларация и инициализация одномерного статического массива с явным указанием размерности массива в 5 ячеек, но с явно присвоенными только 3 элементами, поэтому в остальн./оставш. 2 ячейки будет автоматич. занесено значение 0.
int m[H][W] = {{2, 5}, {3, 7, 4}}; Создание двумерного массива типа int размерностью H на W. Двумерные массивы
Динамический массив
int *y = new int[x]; Создание динамического массива типа int, состоящего из x элементов, а переменная y является ссылкой на этот массив. Доступ к нему осуществляется именно через неё, поскольку переменная y типа int, ссылаться она может только на объекты типа int. О том, что она указатель говорит знак звездочки *.
Массив-вектор vector
vector<int> a(10); Создание динамического массива-вектора a типа int. Явно указывать его размерность в скобках необязательно. Требуется подключ. заголовок vector Динамические массивы-векторы.
x.push_back(5); Помещение значения 5 в конец динамического массива-вектора типа int. Элемент как бы прибавится к концу существующего массива. Присваивать значения можно также и обычным способом, при помощи указания точного индекса массива. Добавление в конец и помещение значения в массив вектор
x.pop_back(); Убрать последний элемент из динамического массива-вектора x. Удаление последнего элемента массива-вектора
x.begin(); Начало массива-вектора Динамический массив-вектор
x.end(); Конец массива-вектора. Динамический массив-вектор
vector<int>::iterator itr; Создание счётчика (итератора) динамического массива-вектора. Итератор динамического массива-вектора
Массив-список list
list<int> l; Создание массива-листа/списка типа int с названием l. Для использ. массивов типа лист требуется подключение <list>
l.push_front(); Добавление элемента в начало динамического массива-списка.
list<int>::iterator li; Создание итератора li динамического массива list.
l.insert(); Вставка элемента в произвольное место массива, что доступна только для массивов типа list.
l.sort(); Автоматическая сортировка элементов в массиве по возрастанию значений, что доступна только в массиве типа list.

Строки в стиле C

Синтаксис Определение
char str[6] = "hello"; Создание строчного массива типа char размерностью в 6 ячеек и занесение в него строки "hello". В конце каждой строки стоит знак 0, который обозначает конец строки, поэтому размерность массива надо определять не менее чем длинна_строки + 1. Этот ноль в конец строки добавляется автоматически компилятором при компоновке.
Такую строки можно легко вывести просто указав имя массива. Перебирать все ячейки массива в этом случае не требуется. Это работает только со строковыми массивами.
char str[] = "hello"; Создание строчного массива типа char без явного указания размерности и занесение в него строки "hello". В конце каждой строки стоит знак 0, который обозначает конец строки, поэтому размерность массива будет автоматически определена как длинна_строки + 1. Этот ноль в конец строки добавляется автоматически компилятором при компоновке.
char str[4] = { 'B', 'a', 'r', 0 };
char str[] = { 'B', 'a', 'r', 0 };
char str[6] = {72,101,108,108,111,0};
char str[] = {72,101,108,108,111,0}; Создание строчного массива типа char без явного указания размерности и занесение в него строки "hello" при помощи указания кодов символов строки "hello". В конце строки стоит знак 0, который обозначает конец строки. Размерность будет автоматически определена по количеству символов.
char str[6] = {'h',101,'l',108,111,0}; Можно использовать смешанный тип.
char str[] = {'h',101,'l',108,111,0};

Ключевые слова

Пример Описание
delete
delete b; Удаление объекта из памяти, на который ссылается указатель b.
delete[] b; Очистка памяти занимаемой массивом, на который ссылался указатель b.
typedef
typedef int Integer; Дать стандартному типу int синоним в виде Integer.
typedef int MyInt[5]; При декларации MyInt[5] в последующем будет создаваться массив из пяти элементов типа int.
typedef int Func(short); При декларации Func sqr будет создаваться прототип функции с названием sqr по шаблону описанному в typedef правиле, то есть будет создаваться прототип такого вида: int sqr(short);.
typedef int (*Func)(short); При декларации Func farray[]={} будет создаваться массив указателей на функции описанных в шаблоне typedef, то есть эта запись равносильная записи int (*Func[])(short)={}.
typedef int Int, *pInt; Дать стандартному типу int синоним в виде Int, и создать указатель на тип int, то есть при использовании pInt в коде будет подставляться int*, то есть указатель на тип int в то время как использование в коде Int будет просто синонимом типа int.

Прототипирование

Пример синтаксиса Описание действия Определение
void func(int, char); Создание прототипа функции func, возвращаемого значения нет (void), аргументы/параметры без названий, перечислены только типы данных — int и char. Прототип функции без названий параметров.
int fnc(char c, double d); Создание прототипа функции fnc, возвращаемое значение типа int, аргументы/параметры c названиями — c типа char, и d типа double. Прототип функции с названиями параметров.
char fn(int, std::string s, double d = 2.4); Создание прототипа функции fn, возвращаемое значение типа char, аргументы/параметры c названиями (s и d), и без (тип int), со значениями по-умолчанию (d) и без (тип int, переменная s). Прототип функции с названиями параметров и без, со значениями по-умолчанию и без.
float f(std::string s, double, char c = 't', int = 7); Создание прототипа функции f, возвращаемое значение типа float, аргументы/параметры c названиями (s и c) и без (типы double и int), со значениями по-умолчанию (переменная c и тип int) и без (переменная s и тип double), с параметром без названия, но со значениями по-умолчанию (тип int). Прототип функции с названиями параметров и без, со значениями по-умолчанию и без, с параметром без названия, но со значениями по-умолчанию.
Bar::Bar(std::string, int i); Создание прототипа конструктора класса Bar. Прототип конструктора

Операции с переменными

Пример синтаксиса Описание действия
Декларация/объявление
int x;
float y;
Декларация переменной x типа int, и объявление переменной y типа float.
Декларация и инициализация
int b = 8; Декларирование переменной b типа int и копирующая инициализация её значением 8.
int b(5); Декларирование переменной b типа int и прямая инициализация её значением 5.
int b{7}; Объявление переменной b типа int и uniform-инициализация значением 7.
Декларация и инициализация нескольких переменных по очереди в одном стейтменте
int x, y, z; Декларация нескольких переменных (x, y, z) типа int по очереди в одном стейтменте.
int x = 4, y, z = 17; Декларация нескольких (x, y, z) и копирующая инициализация некоторых (x, z) переменных типа int по очереди в одном стейтменте.
int x(17), y, z(52); Декларация нескольких (x, y, z) и прямая инициализация некоторых (x, z) переменных типа int.
int a = 7, b = a; Объявление и копирующая инициализация нескольких переменных по очереди в одном стейтменте. Копирующая инициализация одной переменной значением другой.
int c = 44, d(c), e{5}; Определение и инициализация нескольких переменных по очереди в одном стейтменте след. методами: копирующая инициализация, прямая инициализация и uniform-инициализация. Инициализация одной (d) переменной значением другой (c).
Константные переменные
const int Z = 2; Создание константы (константной переменной) времени выполнения Z типа int и инициализация её значением 2.

Перечисления и переменные перечислений

Перечисления
Синтаксис Описание Название
enum File {FILE_O, FILE_W, FILE_C}; Создание перечисления File, содержащее 3 константы с нумерацией по-умолчанию: FILE_O = 1, FILE_W = 2, FILE_C = 3. Перечисление с инициализацией каждой константы по-умолчанию.
enum Food {PIZZA = 8, SALAD, SOUP}; Создание перечисления Food из 3 констант: PIZZA = 8, это явно указано, SALAD = 9 — к значению предыдущей константы прибавляется 1, SOUP = 10. Перечисление с явной инициализацией одной константы, остальные — по-умолчанию.
Переменные типа перечисления
Синтаксис Описание
File fc = FILE_C; Объявление переменной fc типа перечисления File и копирующая инициализация её значением константы FILE_C из перечисления File.
File fw(FILE_W); Объявление переменной fw типа перечисления File и прямая инициализация её значением константы FILE_W из перечисления File.
Создание перечисления и переменных его типа в одном стейтменте
Синтаксис Описание
enum {foo, bar} some; Создание безымянного перечисления из 2 констант: foo, bar, и переменной some типа этого перечисления.
enum some {pl, ps, st} cur, last; Создание перечисления some из 3 констант (pl, ps st), и две переменные (cur, last) типа этого перечисления.

Другое

Синтаксис Описание Название
{int x = 5; …} Создание не именованной области видимости и объявление в ней переменной. Всё созданное в этой области видимости будет доступно только в ней.
Можно получить доступ к объектам из большей области видимости, но не наоборот.
Область видимости
int I;
void f() {int I, i = 1; ::I = 5;}
Сокрытие переменной I, что во внешней области видимости, в функции f, и получение доступа к ней при помощи оператора разрешения области видимости «два двоеточия» (::). Сокрытие переменных
bool operator<(B t) const {return a < t.a;} Переопределение оператора «меньше» (<). Он принимает объект класса B, сравнивает его с переменной a, и возвращает true, если a меньше чем t.a, в противном случае — false. Перегрузка операторов

Хранилища данных

Помимо стандартных массивов в C++ имеются такие стандартные хранилища данных как список (list), вектор (vector) и дек (deque).

См. также