Статические члены класса

Последнее обновление: 10.03.2023

Кроме переменных и методов, которые относятся непосредственно к объекту, C++ позволяет определять переменные и методы, которые относятся непосредственно к классу или иначе говоря статические члены класса. Статические переменные и методы относят в целом ко всему классу. Для их определения используется ключевое слово static.

Статические поля

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

Показательным примером статических переменных являются различные счетчики. Например, нам надо хранить количество созданных объектов. Такое количество относится классу, однако не зависит от конкретного объекта. Посмотрим на примере:

#include <iostream>

class Person
{
public:
	Person(std::string p_name, unsigned p_age)
	{
        ++count;    // при создании нового объекта увеличиваем счетчик
		name = p_name;
        age = p_age;
	}
    void print_count()
    {
        std::cout << "Created " << count << " objects" << std::endl;
    }
private:
	std::string name;
    unsigned age;
    static inline unsigned count{};  // статическое поле - счетчик объектов Person
};

int main()
{
    Person tom{"Tom", 38};
    Person bob{"Bob", 42};
    Person sam{"Sam", 25};
    tom.print_count();
    bob.print_count();
    sam.print_count();
}

Здесь в классе Person определена статическая переменная count с помощью ключевого слова static:

static inline unsigned count{}; // инициализируем нулем

Обратите внимание, после static идет ключевое слово inline. Это ключевое слово в принципе необязательно для статических переменных и необходимо конкретно в данном случае для инициализации переменной count. В данном случае нулем.

При создании каждого нового объекта в конструкторе увеличиваем счетчик на единицу:

Person(std::string p_name, unsigned p_age)
{
    ++count;    // при создании нового объекта увеличиваем счетчик

В функциях класса Person мы можем обращаться к этой статической переменной. Например, в функции print_count выводим ее значение на консоль:

void print_count()
{
    std::cout << "Created " << count << " objects" << std::endl;
}

Для теста в функции main создаем три объекта Person и затем у каждого вызываем функцию print_count:

tom.print_count();
bob.print_count();
sam.print_count();

Но поскольку переменная count статическая и относится ко всему классу в целом и не зависит от конкретного объекта, во всех трех случаях будет вывtдено число 3.

Статические функции

Статические функции также принадлежат классу в целом и не зависят от любого отдельного объекта класса. Обычно статические функции-члены используются для работы со статическими переменными. Например, в примере выше функция print_count() выводит значение статической переменной count и никак не зависит от конкретного объекта, не использует и не изменяет переменные и функции объектов. Поэтому такую функцию можно и даже лучше сделать статической:

#include <iostream>

class Person
{
public:
	Person(std::string p_name, unsigned p_age)
	{
        ++count;    // при создании нового объекта увеличиваем счетчик
		name = p_name;
        age = p_age;
	}
    // статическая функция
    static void print_count()
    {
        std::cout << "Created " << count << " objects" << std::endl;
    }
private:
	std::string name;
    unsigned age;
    static inline unsigned count{};  // статическое поле - счетчик объектов Person
};

int main()
{
    Person tom{"Tom", 38};
    Person bob{"Bob", 42};
    Person sam{"Sam", 25};
    tom.print_count();  // Created 3 objects
}

Для определения статической функции перед ней также указывается ключевое слово static:

static void print_count() 

К подобным функциям также можно обращаться через имя объекта:

tom.print_count();

Обращение к статическим членам класса

Как выше было продемонстрировано, для обращения к статическим членам можно использовать имя любого объекта. Однако C++ также поддерживает и другой синтаксис:

класс::член_класса

После имени класса идет оператор :: и имя статического компонента класса. Например:

#include <iostream>

class Person
{
public:
    static inline unsigned maxAge{120};     // статическая публичная переменная
	Person(std::string p_name, unsigned p_age)
	{
        ++count;
		name = p_name;
        if(p_age < maxAge)  // если значение не больше максимального
            age = p_age;
	}
    // статическая функция
    static void print_count()
    {
        std::cout << "Created " << count << " objects" << std::endl;
    }
private:
	std::string name;
    unsigned age{1};
    static inline unsigned count{};  // статическая приватная переменная
};

int main()
{
    Person tom{"Tom", 38};
    Person bob{"Bob", 42};
    Person sam{"Sam", 25};
    
	// обращаемся к статической функции print_count
    Person::print_count();
	// обращаемся к статической переменной maxAge
    std::cout << "Max age: " << Person::maxAge << std::endl;
	// изменяем статическую переменную maxAge
	Person::maxAge = 110;
    std::cout << "Max age: " << Person::maxAge << std::endl;
}

Здесь добавлена публичная статическая переменная maxAge, которая представляет максимальный возраст. Поскольку этот показатель не зависит от определенного объекта и относится в целом к классу объектов Person (справедливо для всех людей), то определяем такую переменную как статическую. В конструкторе используем эту переменную для верификации переданного в конструктор возраста. Если он больше максимального, то возраст получает значение по умолчанию - 1.

Далее в функции main мы можем по имени класса обратиться к статической функции print_count и переменной maxAge:

Person::print_count();
Person::maxAge

Консольный вывод программы:

Created 3 objects
Max age: 120
Max age: 110

Статические константы

Также можно определять статические константы. Так, в примере выше маловероятно, что значение maxAge будет меняться. Поэтому мы можем определить ее как константу. Ее значения нельзя будет изменить, а во остальном работа с ней идет также как и со статическими переменными:

#include <iostream>

class Person
{
public:
    static inline const unsigned maxAge{120};     // статическая константа
	Person(std::string p_name, unsigned p_age)
	{
        ++count;
		name = p_name;
        if(p_age < maxAge)  // если значение не больше максимального
            age = p_age;
	}
    // статическая функция
    static void print_count()
    {
        std::cout << "Created " << count << " objects" << std::endl;
    }
private:
	std::string name;
    unsigned age{1};
    static inline unsigned count{};  // статическая приватная переменная
};

int main()
{
    Person tom{"Tom", 38};
    Person bob{"Bob", 42};
    
	// обращаемся к статическим компонентам класса
    Person::print_count();
    std::cout << "Max age: " << Person::maxAge << std::endl;
}
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850