Spec-Zone.ru › C++

Классы

Класс — это определяемый пользователем тип.

Тип класса определяется спецификатором класса, который встречается в decl-specifier-seq синтаксиса объявления. Синтаксис спецификатора класса см. в разделе объявление класса.

Класс может содержать следующие виды членов:

1) данные-члены:
a) нестатические данные-члены, в том числе битовые поля.
b) статические данные-члены
2) функции-члены:
a) нестатические функции-члены
b) статические функции-члены
3) вложенные типы:
a) вложенные классы и перечисления, определённые внутри определения класса
b) псевдонимы существующих типов, определённые с помощью typedef или объявлений псевдонимов типов (начиная с C++11)
c) имя класса внутри его собственного определения выступает в качестве общедоступного псевдонима типа для самого себя при выполнении поиска (кроме случаев, когда оно используется для именования конструктора): это называется внедрённым именем класса
4) перечислители всех неограниченных перечислений, определённых внутри класса, а также перечислители, введённые объявлениями using или объявлениями using-enum(начиная с C++20)
5) шаблоны-члены (шаблоны переменных, (начиная с C++14)шаблоны классов или шаблоны функций) могут встречаться в теле любого класса/структуры/объединения с областью видимости вне функции.

Все члены определяются одновременно в определении класса; их нельзя добавить в уже определённый класс (в отличие от членов пространств имён).

Член класса T не может использовать T в качестве имени, если этот член является

  • статическим данным-членом,
  • функцией-членом,
  • типом-членом,
  • шаблоном-членом,
  • перечислителем перечисления (если только перечисление не является ограниченным)(начиная с C++11), или
  • членом анонимного объединения, являющегося членом класса.

Однако нестатический данные-член может использовать имя T, если нет объявленных пользователем конструкторов.

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

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

Класс с конструктором constexpr является литеральным типом: объектами этого типа можно манипулировать с помощью функций constexpr во время компиляции.

(начиная с C++11)

Свойства классов

Тривиально копируемый класс

Тривиально копируемый класс — это класс, который

  • имеет хотя бы один подходящий конструктор копирования, конструктор перемещения, оператор присваивания копированием или оператор присваивания перемещением,
  • каждый подходящий конструктор копирования является тривиальным
  • каждый подходящий конструктор перемещения является тривиальным
  • каждый подходящий оператор присваивания копированием является тривиальным
  • каждый подходящий оператор присваивания перемещением является тривиальным, и
  • имеет неудалённый тривиальный деструктор.

Тривиальный класс

Тривиальный класс — это класс, который

  • является тривиально копируемым, и
  • имеет один или несколько подходящих конструкторов по умолчанию, каждый из которых является тривиальным.
(устарело в C++26)

Класс со стандартной компоновкой

Класс со стандартной компоновкой — это класс, который

  • не имеет нестатических данных-членов типа класса без стандартной компоновки (или массива таких типов) либо ссылочного типа,
  • не имеет виртуальных функций и виртуальных базовых классов,
  • имеет одинаковый контроль доступа для всех нестатических данных-членов,
  • не имеет базовых классов без стандартной компоновки,
  • только один класс в иерархии имеет нестатические данные-члены, и
  • неформально: ни один из базовых классов не имеет того же типа, что и первый нестатический данные-член. Формально: если обозначить класс как S, множество M(S) типов не содержит ни одного элемента в качестве базового класса, где M(X) для типа X определяется следующим образом:
    • Если X — тип класса (не объединения), не имеющего (возможно, унаследованных) нестатических данных-членов, множество M(X) пусто.
    • Если X — тип класса (не объединения), первый нестатический данные-член которого имеет тип X0 (при этом указанный член может быть анонимным объединением), множество M(X) состоит из X0 и элементов M(X0).
    • Если X — тип объединения, множество M(X) представляет собой объединение всех M(Ui) и множества, содержащего все Ui, где каждый Ui — тип i-го нестатического данные-члена X.
    • Если X — тип массива с типом элемента Xe, множество M(X) состоит из Xe и элементов M(Xe).
    • Если X — тип, не являющийся ни классом, ни массивом, множество M(X) пусто.

Структура со стандартной компоновкой — это класс со стандартной компоновкой, определённый с ключевым словом класса struct или ключевым словом класса class. Объединение со стандартной компоновкой — это класс со стандартной компоновкой, определённый с ключевым словом класса union.

(начиная с C++11)

Класс с неявным временем жизни

Класс с неявным временем жизни — это класс, который

  • является агрегатом, деструктор которого не является объявленным пользователем(до C++11)предоставленным пользователем(начиная с C++11), или
  • имеет хотя бы один тривиальный подходящий конструктор и тривиальный неудалённый деструктор.

Примечание: свойство неявного времени жизни уточнено в отчёте об исправлении дефекта P0593R6.

POD-класс

POD-класс — это класс, который

  • является агрегатом,
  • не имеет объявленного пользователем оператора присваивания копированием,
  • не имеет объявленного пользователем деструктора и
  • не имеет нестатических данных-членов типа класса, не являющегося POD-классом (или массива таких типов), либо ссылочного типа.
(до C++11)
  • является тривиальным классом,
  • является классом со стандартной компоновкой и
  • не имеет нестатических данных-членов типа класса, не являющегося POD-классом (или массива таких типов).
(начиная с C++11)

POD-структура — это POD-класс, не являющийся объединением. POD-объединение — это объединение, являющееся POD-классом.

(устарело в C++20)

Отчёты об исправлениях дефектов

Следующие отчёты об исправлениях дефектов, изменяющие поведение, были применены задним числом к ранее опубликованным стандартам C++.

DR Применён к Поведение согласно опубликованному стандарту Корректное поведение
CWG 148 C++98 POD-классы не могли содержать указатели на члены,
которые сами являются POD-типами (скалярными типами)
ограничение снято
CWG 383 C++98 операторы присваивания копированием или деструкторы могли быть
объявлены пользователем в POD-классах, если они не определены
не допускается
CWG 1363 C++11 класс, имеющий одновременно тривиальные и нетривиальные
конструкторы по умолчанию, мог быть тривиальным
он является нетривиальным
CWG 1496 C++11 класс, имеющий только конструкторы,
все определённые как удалённые, мог быть тривиальным
он является нетривиальным
CWG 1672 C++11 класс мог быть классом со стандартной компоновкой,
если у него несколько пустых базовых классов
он не является классом со стандартной компоновкой
CWG 1734 C++11 тривиально копируемый класс не мог иметь нетривиальные
удалённые конструкторы копирования/перемещения или операторы присваивания
может быть тривиальным, если они удалены
CWG 1813 C++11 класс никогда не был классом со стандартной компоновкой, если у него был
базовый класс, наследующий нестатический данные-член
он может быть классом со стандартной компоновкой
CWG 1881 C++11 в классе со стандартной компоновкой и его базовых классах
безымянные битовые поля могли объявляться в
другом классе, объявляющем данные-члены
все нестатические данные-члены
и битовые поля должны быть впервые
объявлены в одном и том же классе
CWG 1909 C++98 шаблон-член мог иметь то же имя, что и его класс запрещено
CWG 2120 C++11 при определении класса со стандартной компоновкой определение M(X)
не учитывало случай, когда
первый член класса является массивом
этот случай учтён в
определении M(X)
CWG 2605 C++98 у класса с неявным временем жизни мог быть деструктор, предоставленный пользователем запрещено

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/language/classes

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API