Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООП_ Лекция №05 - Вспомогательные средства для создания классов.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
75.16 Кб
Скачать

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

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

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

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

Из отсутствия неявно передаваемого указателя this в статических функциях-членах вытекает ряд ограничений на содержащийся в их телах программный код:

  1. Нельзя напрямую по имени обращаться к нестатическим переменным-членам класса, поскольку нет объекта, через который можно было бы получить к ним доступ.

  2. Нельзя напрямую по имени вызывать нестатические функции-члены, поскольку нет объекта, указатель на который передавать в качестве this при вызове.

  3. Нельзя совмещать модификаторы static и const, поскольку модификатор const для функций-членов влияет на тип неявно передаваемого указателя this, которого статические функции-члены не получают.

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

В приведенном ниже примере используются как статическая переменная-член, так и статическая функция-член (по сути, функция играет роль статического варианта метода-геттера). Имеется класс, описывающий оценку студента по некоторой дисциплине. В статической переменной-члене ms_MaxMark сохраняется максимальная оценка, которую получал любой из экземпляров, автоматически корректируемая в конструкторе объектов. А при помощи статической функции-члена GetMaxMark определенный на текущий момент максимум оценки возвращается клиентскому коду:

student.hpp

#ifndef _STUDENT_HPP_

#define _STUDENT_HPP_

class Student

{

// Обычные (нестатические) переменные-члены (храним в объекте)

const char * m_LastName;

const int m_Mark;

// Статическая переменная-член (храним независимо от объектов в сегменте данных).

// Содержит текущую накопленную максимальную оценку студентов.

static int ms_MaxMark;

public:

// Объявление конструктора

Student ( const char * _lastName, int _mark );

// Статическая функция-член: возвращает текущую накопленную максимальную оценку

static int GetMaxMark ();

};

// Реализация статической функции-члена.

// Модификатор static в выносной реализации не указывается.

inline int Student::GetMaxMark ()

{

return ms_MaxMark; // Доступ к этой переменной разрешен.

// Обращаться к m_LastName или m_Mark здесь нельзя

}

#endif // _STUDENT_HPP_

student.cpp

#include “student.hpp”

// Определение статической переменной-члена, значение 0 по умолчанию

int Student::ms_MaxMark;

// Реализация конструктора

Student::Student ( const char * _lastName, int _mark )

: m_LastName( _lastName ),

m_Mark( _mark )

{

// Обновляем максимальную оценку, если новая оценка выше

if ( m_Mark > ms_MaxMark )

// Конструктор является обычной нестатической функцией-членом)

// Соответственно, может получать доступ к любой переменной класса.

ms_MaxMark = m_Mark;

}

test.cpp

#include “student.hpp”

#include <iostream>

int main ()

{

// Создаем несколько экземпляров класса с различными оценками

Student s1( "Ivanov", 75 );

Student s2( "Petrov", 80 );

Student s3( "Sidorov", 60 );

// Выводим накопленный максимум через вызов статической функции-члена

std::cout << "Maximum mark among students: "

<< Student::GetMaxMark() // this здесь не передается

<< std::endl;

// Вызов через любой объект также возможен, tnis не передается

// ... << s1.GetMaxMark() ... <<

}

Вывод программы на консоль будет содержать следующее:

Maximum mark among students: 80