Перейти к содержимому
Теория · Классы и ООП · урок 1 из 13

struct, class и доступ

Прямоугольник задают два числа — ширина и высота. В отдельных переменных их можно спутать с размерами другого прямоугольника, а функции площади приходится передавать оба числа. Ключевое слово struct собирает такие данные в один новый тип:

C++
#include <iostream>

struct Rect {
    int width = 0;
    int height = 0;
    int area() { return width * height; }
};

int main() {
    Rect r;
    r.width = 3;
    r.height = 4;
    std::cout << r.area() << '\n';  // 12
}

Поля и методы

Rect — класс (class): тип, который хранит данные вместе с функциями для работы с ними. Переменные внутри класса называют полями (data members), а функции — методами (member functions). Описание класса само объектов не создаёт: переменная r — объект типа Rect, и у каждого объекта свои поля. Начальное значение полю задают через = или фигурные скобки, как int width = 0;; круглые скобки здесь не работают.

К полям и методам объекта обращаются через точку: r.width, r.area(). Метод всегда вызывают для конкретного объекта, и внутри метода имена полей означают поля этого объекта. В вызове r.area() имя width — это r.width.

Поля с одинаковым доступом лежат в объекте в порядке объявления (declaration). Но sizeof(Rect) может оказаться больше суммы размеров полей. Компилятор (compiler) вправе добавить пустые байты между полями и в конце объекта, чтобы каждое поле получило удобный для процессора адрес.

public и private

Метки public: и private: задают, кому доступны поля и методы. Всё, что идёт после public:, доступно любому коду, а всё, что после private:, — только методам самого класса. Закрытое поле нельзя испортить снаружи: его меняют только методы, а они следят, чтобы значение оставалось верным.

C++
class Counter {
public:
    void add() {
        ++count_;
    }
    int value() {
        return count_;
    }

private:
    int count_ = 0;
};

Для объекта Counter c; код снаружи может вызвать c.add() и c.value(), но строка c.count_ = 100; не скомпилируется. Подчёркивание в конце имени — распространённое соглашение для закрытых полей.

struct и class различаются только доступом по умолчанию: у struct поля и методы без метки открыты, а у class — закрыты. Поэтому struct обычно пишут для наборов открытых данных, а class — когда у типа есть закрытые поля.

Частая ошибка

Тип объявили через class и забыли метку public::

C++
class Rect {
    int width = 0;
    int height = 0;
};

int main() {
    Rect r;
    r.width = 3;  // ✗
}
TEXT
error: 'width' is a private member of 'Rect'

В class поля без метки закрыты, поэтому из main поле width недоступно. Если тип — набор открытых данных, объявите его через struct. Если полям нужно остаться закрытыми, добавьте открытые методы, которые их меняют.