- •Классы и заголовочные файлы Отделение объявления от реализации
- •Int m_month;
- •Int m_year;
- •Int getValue () { return m_value ; }
- •Int getValue () {return m_value;}
- •Классы и заголовочные файлы
- •Int getDay () {return m_day;}
- •Void Date::SetDate (int day, int month, int year) {
- •Параметры по умолчанию
- •Библиотеки
- •Заключение
- •Классы и const
- •Константные объекты классов
- •Int m_value;
- •Int getValue () { return m_value ; }
- •Int main () {
- •Константные методы классов
- •Int m_value;
- •Int m_value;
- •Int m_value;
- •Константные ссылки и классы
- •Int getDay () {return m_day;}
- •Void printDate (const Date &date) {
- •Int main () {
- •Int m_month;
- •Int m_year;
- •Void setDate (int day, int month, int year) {
- •Перегрузка константных и неконстантных функций
- •Int main () {
- •Статические переменные-члены класса
- •Статические переменные-члены класса
- •Int generateId () {
- •Int main () {
- •Int main () {
- •Int main () {
- •Статические члены не связаны с объектами класса
- •Int main () {
- •Определение и инициализация статических переменных-членов класса
- •Инициализация статических переменных-членов внутри тела класса
- •Использование статических переменных-членов класса
- •Int getId() const { return m_id; }
- •Int main () {
- •Статические методы класса
- •Int main () {
- •Int main () {
- •Статические методы не имеют указателя this
- •Int main () {
- •Предупреждение о классах со всеми статическими членами
- •Int main () {
- •Дружественные функции и классы
- •Int m_value;
- •Void reset (Anything &anything) {
- •Int main () {
- •Int m_value;
- •Дружественные функции и несколько классов
- •Дружественные классы
- •Примечания о дружественных классах:
- •Дружественные методы
- •If (m_displayIntFirst)
- •Int m_intValue;
- •Values (int intValue, double dValue) {
- •Анонимные объекты
- •Int main () {
- •Анонимные объекты класса
- •Int m_dollars;
- •Int getDollars () const {return m_dollars;}
- •Int main () {
- •Int m_dollars;
- •Int getDollars() const { return m_dollars; }
- •Int main () {
- •Вложенные типы данных в классах
- •Int main () {
- •Вложенные пользовательские типы данных в классах
- •Int main () {
- •Другие вложенные пользовательские типы данных в классах
Инициализация статических переменных-членов внутри тела класса
Есть несколько обходных путей определения статических членов внутри тела класса.
Во-первых, если статический член является константным
интегральным типом (целочисленных типов, к которому относятся и char, и bool) или константным перечислением, то статический член может быть инициализирован внутри тела класса:
class Anything {
public:
static const int s_value = 5; // статическую константную переменную //типа int можно объявить и инициализировать напрямую
};
Поскольку здесь статическая переменная-член является целочисленной константой, то дополнительной строки явного определения вне тела класса уже не требуется.
Во-вторых, начиная с C++11 статические члены constexpr любого типа данных, поддерживающие инициализацию constexpr, могут быть инициализированы внутри тела класса:
#include <array>
class Anything {
public:
static constexpr double s_value = 3.4; // хорошо
static constexpr std::array <int, 3> s_array = {3, 4, 5 }; // это работает //даже с классами, которые поддерживают инициализацию constexpr
};
Использование статических переменных-членов класса
Зачем использовать статические переменные-члены внутри классов? Для присваивания уникального идентификатора каждому объекту класса (как вариант):
#include <iostream>
class Anything {
private:
static int s_idGenerator;
int m_id;
public:
Anything () {m_id = s_idGenerator++;} // увеличиваем значение //идентификатора для следующего объекта
Int getId() const { return m_id; }
};
// Мы определяем и инициализируем s_idGenerator несмотря на то, что //он объявлен как private.
// Это нормально, поскольку определение не подпадает под действия спецификаторов доступа
int Anything::s_idGenerator = 1; // начинаем наш ID-генератор со
//значения 1
Int main () {
Anything first;
Anything second;
Anything third;
std::cout << first.getID () << '\n';
std::cout << second.getID () << '\n';
std::cout << third.getID () << '\n';
return 0;
}
Результат выполнения программы:
1
2
3
Поскольку s_idGenerator является общим для всех объектов класса Anything, то при создании нового объекта класса Anything конструктор захватывает текущее значение s_idGenerator, а затем увеличивает его для следующего объекта.
Это гарантирует уникальность идентификаторов для каждого созданного объекта класса Anything.
Статические переменные-члены также могут быть полезны, когда классу необходимо использовать внутреннюю таблицу поиска, например, массив, используемый для хранения набора предварительно вычисленных значений.
Делая таблицу поиска статической, для всех объектов класса создастся только одна копия, нежели отдельная для каждого объекта класса. Это поможет сэкономить значительное количество памяти.
Статические методы класса
Статические переменные-члены — это члены, которые принадлежат классу, а не его объектам.
Если статические переменные-члены являются открытыми, то мы можем получить к ним доступ напрямую через имя класса и оператор разрешения области видимости.
Но что, если статические переменные-члены являются закрытыми? Рассмотрим следующий код:
class Anything {
private:
static int s_value;
};
int Anything::s_value = 3; // определение статического члена, несмотря
// на то, что он является private
