C++. Классы. Виды функций-членов класса. Обычные функции-члены. Статические (static) функции-члены. Примеры использования
Данная тема базируется на использовании функций-членов класса, ориентированных на компилятор Visual C++. В реализациях компиляторов разных разработчиков могут быть существенные отличия, в особенности что касается статических функций-членов.
Содержание
- 1. Какие виды функций-членов можно объявлять в классах?
- 2. Пример объявления класса, содержащего обычные функции-члены
- 3. Пример объявления класса, содержащего статические (static) функции-члены
- 4. Какое отличие статических функций-членов от обычных функций-членов
- 5. В каких случаях целесообразно применять статические (static) функции-члены класса
- Связанные темы
Поиск на других ресурсах:
1. Какие виды функций-членов можно объявлять в классах?
В классах можно объявлять следующие виды функций:
- обычные функции-члены. Это функции, в объявлении которых не используются дополнительные ключевые слова (const, volatile, static);
- статические функции. Это функции, объявленные с ключевым словом static;
- константные функции. Это функции, которые объявлены с ключевым словом const;
- функции-члены, которые возвращают непостоянный объект. Это функции, объявленные с ключевым словом volatile;
- функции-члены с константным (const) указателем this;
- функции-члены с непостоянным (volatile) указателем this;
- встроенные (inline) функции-члены.
2. Пример объявления класса, содержащего обычные функции-члены
В данном примере объявлен класс CLine, описывающий линию на координатной плоскости. Линия состоит из координат точек (x1; y1), (x2; y2). Класс содержит простые функции члены, объявленные в разделе public. С помощью этих функций-членов осуществляется чтение/модификация внутренних переменных класса.
// класс, который описывает линию на координатной плоскости class CLine { int x1, y1; int x2, y2; public: CLine(void); ~CLine(void); // методы класса void SetLine(int nx1, int ny1, int nx2, int ny2); int GetX1(void) { return x1; } int GetY1(void) { return y1; } int GetX2(void) { return x2; } int GetY2(void) { return y2; } }; // Реализация методов класса // конструктор по умолчанию CLine::CLine(void) { x1 = y1 = 0; x2 = y2 = 1; } // деструктор CLine::~CLine(void) { } // реализация простой функции-члена класса void CLine::SetLine(int nx1, int ny1, int nx2, int ny2) { x1 = nx1; y1 = ny1; x2 = nx2; y2 = ny2; }
Использование класса в другом программном коде
// объявление объекта класса CLine CLine CL; int t; // вызов функций-членов класса CL.SetLine(5, 6, 10, 20); t = CL.GetX2(); // t = 10 t = CL.GetY1(); // t = 6
3. Пример объявления класса, содержащего статические (static) функции-члены
В данном примере объявлен класс CCircle, описывающий окружность на координатной плоскости. Класс реализует следующие внутренние члены данных и методы:
- внутренние переменные (члены) класса x, y, r (координаты центра и радиус окружности);
- конструктор класса CCircle(), который определяет окружность с радиусом r=1 и центром в точке (0; 0);
- статическую функцию-член класса SetData1(), которая устанавливает значение глобальных переменных xx, yy, rr объявленных за пределами класса;
- обычную (нестатическую) функцию-член класса SetData2(), которая изменяет значение внутренних переменных x, y, r класса;
- обычные (нестатические) методы класса, реализующие чтение значений внутренних переменных класса x, y, r и глобальных переменных xx, yy, rr.
// класс, описывающий окружность на координатной плоскости class CCircle { // внутренние переменные класса int x, y; // координаты центра окружности int r; // радиус окружности public: // конструктор класса CCircle(void); // статический метод класса - только для глобальных переменных static void SetData1(int nx, int ny, int nr); // обычные (нестатические) методы класса // установить новые значения внутренних переменных класса void SetData2(int nx, int ny, int nr); // взять значение внутренних переменных класса int GetX(void) { return x; } int GetY(void) { return y; } int GetR(void) { return r; } // взять значение глобальных переменных класса int GetXX(void); int GetYY(void); int GetRR(void); }; // глобальные переменные int xx, yy, rr; // эти переменные может изменять статическая функция-член класса // конструктор класса CCircle::CCircle(void) { // заполнение значений внутренних (локальных) переменных x = 0; y = 0; r = 1; } // статическая функция-член класса void CCircle::SetData1(int nx, int ny, int nr) { // присваивание значений глобальным переменным, объявленным за пределами класса xx = nx; yy = ny; rr = nr; // работать с внутренними переменными класса в статической функции запрещено // x = nx; // Запрещено! Ошибка: "... illegal reference to non-static member 'CCircle::х' // y = ny; // тоже запрещено } // установить новые значения обычных (нестатических) методов класса void CCircle::SetData2(int nx, int ny, int nr) { x = nx; y = ny; r = nr; } // прочитать значение глобальных переменных класса int CCircle::GetXX(void) { return xx; } int CCircle::GetYY(void) { return yy; } int CCircle::GetRR(void) { return rr; }
Изменять значения внутренних переменных класса с статической функции-члена класса запрещено. Если в функции SetData1() попробовать изменить значения внутренних переменных класса x, y
void CCircle::SetData1(int nx, int ny, int nr) { ... x = nx; y = ny; ... }
то компилятор выдаст ошибку
... illegal reference to non-static member 'CCircle::x'
Если нужно изменить значения внутренних переменных класса в статической функции, тогда этой функции нужно передать указатель this класса.
Нижеследующий программный код демонстрирует использование статической функции-члена для класса Circle
// использование класса CCircle CCircle C1; int tx, ty, tr; // дополнительные переменные // вызов статической функции-члена C1.SetData1(2, 3, 4); // изменяются только глобальные переменные xx, yy, rr // прочитать значение внутренних переменных класса tx = C1.Get(); // tx = 0 - внутренние переменные x,y,r инициализированы конструктором класса tr = C1.Get(); // tr = 1 // прочитать значение глобальных переменных, объявленных за пределами класса tx = C1.GetXX(); // tx = 2 ty = C1.GetYY(); // ty = 3 // вызов обычной (нестатической) функции-члена класса C1.SetData2(2, 3, 4); // изменяются только внутренние переменные x, y, r tx = C1.GetX(); // tx = 2 tr = C1.GetR(); // tr = 4 // другой способ вызова статической функции-члена CCircle::SetData1(7, 8, 9); tx = C1.GetXX(); // tx = 7 ty = C1.GetYY(); // ty = 8
4. Какое отличие статических функций-членов от обычных функций-членов
Основные отличия статических функций-членов от обычных:
- вызвать статическую функцию-член можно без ссылки на объект класса, например CMyClass::MyStaticFuntion(…). В этом случае используется оператор расширения области видимости ‘::’;
- статические функции-члены не получают указателя this класса. Это значит, что они не могут получить доступ к внутренним членам данных класса. Исключением есть статические члены-данные класса, которые объявлены с ключевым словом static;
- в C++ статическая функция-член класса есть глобальной. Поэтому ее целесообразно использовать для изменения значений глобальных переменных, которые объявлены за пределами класса но имеют применение в классе.
5. В каких случаях целесообразно применять статические (static) функции-члены класса
Статические функции-члены класса целесообразно применять в случаях, когда в классе нужно использовать глобальные переменные, которые есть общими для разных объектов (экземпляров) этого класса.
Связанные темы
- Описание функции. Фактические и формальные параметры. Передача параметров в функцию по значению и по адресу. Прототип функции
- Функции и массивы. Передача одномерного и многомерного массива в функцию. Передача структуры и класса в функцию