Понятие класса

Класс — это определяемый пользователем тип. Его имя становится зарезервированным словом в его области видимости и даёт возможность создавать переменные этого типа.

Экземпляр класса или, по-другому, объект — это переменная классового типа.

Пример описания класса

struct Student{
    int age;
    string name;
    int group;

    void print() const {
        cout << "name: " << name;
        cout << ", group: " << group;
        cout << ", age: " << age << endl;
    }
};

Первое и главное отличие класса (в том числе "С++-структуры") от Си-структуры в том, что её членами (полями) являются не только атрибуты (переменные), но и функции. Этим С++ структура похожа на пространство имён (namespace). Действительно, класс сам себе образует пространство имён.

Функции, живущие внутри класса называются методами. Синтаксически обращение к методам экземпляра класса происходит так же, как и обращение к полям-атрибутам — через точку.

Student s;
s.name = "Vasya";
s.age = 17;
s.group = 112;
s.print();

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

Student s1, s2;
s1 = s2;
int mark = examine(s1);
s2 = getNewStudent();

Статическое связывание методов

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

Abitur x;
Student y;
Teacher z;
x.print();
y.print();
z.print();

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

Порождение типа

Описание класса порождает новый тип. Например, ниже описываются три переменные трех различных типов:

struct X { int a; };
struct Y { int a; };
X a1;
Y a2;
int a3;

Отсюда следует, что следующие присваивания приводят к несоответствию типов:

a1 = a2;   // ошибка: Y присваивается X
a1 = a3;   // ошибка: int присваивается X

Замечание

Объекты пустого класса имеют ненулевой размер.

class voidClass{ /*there is nothing here...*/ };
cout << "sizeof(voidClass) = " << sizeof(voidClass) << endl;