8.5. Гарантия единственности копии переменной-члена
8.5. Гарантия единственности копии переменной-члена
Проблема
Имеется переменная-член, у которой должен быть только один экземпляр независимо от числа создаваемых экземпляров класса. Этот тип переменных-членов обычно называется статическими членами или переменными класса — в противоположность переменным экземпляра, свои копии которых создаются для каждого объекта класса.
Решение
Объявите переменную-член с ключевым словом static, затем инициализируйте ее в отдельном исходном файле (но не в заголовочном файле, где она объявлена), как показано в примере 8.5.
Пример 8.5. Использование статических переменных-членов
// Static.h
class OneStatic {
public:
int getCount() {return count;}
OneStatic();
protected:
static int count;
};
// Static.cpp
#include "Static.h"
int OneStatic::count = 0;
OneStatic::OneStatic() {
count++;
}
// StaticMain.cpp
#include <iostream>
#include "static.h"
using namespace std;
int main() {
OneStatic a;
OneStatic b;
OneStatic c;
cout << a.getCount() << endl;
cout << b.getCount() << endl;
cout << c.getCount() << endl;
}
Обсуждение
static — это способ C++ разрешить создание только одной копии чего-либо. Если переменную-член объявить как static, то будет создана только одна такая переменная вне зависимости от количества созданных объектов этого класса. Аналогично, если объявить как static переменную функции, она будет создана только один раз и будет хранить свое значение от одного вызова функции к другому. Однако в случае с переменными-членами, чтобы убедиться, что переменная создана правильно, требуется проделать несколько больше работы. Именно по этой причине в примере 8.5 показано три файла.
Во-первых, при объявлении переменной требуется использовать ключевое слово static. Это достаточно просто: добавьте это ключевое слово в заголовок класса, находящийся в заголовочном файле Static.h.
protected:
static int count;
После этого требуется определить эту переменную в исходном файле. При этом для нее будет выделена память. Это делается с помощью указания полного имени переменной и присвоения ей значения, как здесь.
int OneStatic::count = 0;
В примере 8.5 я поместил это определение в файл Static.cpp. Именно так вы и должны делать — не помещайте определение в заголовочный файл. Если это сделать, память будет выделена в каждом файле реализации, включающем этот заголовочный файл, и либо возникнут ошибки компиляции, либо, что хуже, в памяти появятся несколько экземпляров этой переменной. Это не то, что требуется при использовании переменной-члена static.
В главном файле StaticMain.cpp вы можете видеть то, что происходит. Создается несколько экземпляров класса OneStatic, и каждый раз конструктор по умолчанию OneStatic инкрементирует статическую переменную. В результате вывод main из StaticMain.cpp имеет вид:
3
3
3
Каждый вызов getCount возвращает одно и то же целое значение, даже несмотря на то, что он делается для различных экземпляров класса.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
2. Профессиональная деятельность члена вашей семьи
2. Профессиональная деятельность члена вашей семьи Если вы не работаете на данный момент или вы – молодой человек без опыта работы, для вас следующий пункт. Возможно, кто-то из вашей семьи что-то очень хорошо делает. Например, ваш брат или сестра – фотограф, финансовый
9. Гарантия
9. Гарантия Вы гарантируете 100-процентный успех. Если опасаетесь, что все начнут требовать у вас возврата денег, отбросьте необоснованные страхи: на этом настаивает не более 1 % всех клиентов. Делайте солидную гарантию на 365 дней –
2.1. Обеспечение единственности подключения заголовочного файла
2.1. Обеспечение единственности подключения заголовочного файла ПроблемаУ вас есть заголовочный файл, который подключается несколькими другими файлами. Вы хотите убедиться, что препроцессор сканирует объявления в заголовочном файле не более одного раза.РешениеВ
2.2. Обеспечение единственности экземпляра переменной при большом количестве исходных файлов
2.2. Обеспечение единственности экземпляра переменной при большом количестве исходных файлов ПроблемаТребуется, чтобы одна и та же переменная использовалась различными модулями программы, а копия переменной должна быть только одна. Другими словами, это должна быть
Гарантия CLS-совместимости
Гарантия CLS-совместимости Как вы узнаете из текста этой книги, в C# имеется ряд программных конструкций, которые яе являются CLS-совместимыми. Однако хорошим известием является то, что вы можете заставить компилятор C# выполнять проверку вашего программного кода на
3.2.2. Имя переменной
3.2.2. Имя переменной Имя переменной, или идентификатор, может состоять из латинских букв, цифр и символа подчеркивания. Прописные и строчные буквы в именах различаются. Язык С++ не ограничивает длину идентификатора, однако пользоваться слишком длинными именами типа
8.5.4. Определение члена пространства имен
8.5.4. Определение члена пространства имен Мы видели, что определение члена пространства имен может появиться внутри определения самого пространства. Например, класс matrix и константа pi появляются внутри вложенного пространства имен MatrixLib, а определения функций operator+() и
13.6.1. Тип члена класса
13.6.1. Тип члена класса Указателю на функцию нельзя присвоить адрес функции-члена, даже если типы возвращаемых значений и списки параметров полностью совпадают. Например, переменная pfi – это указатель на функцию без параметров, которая возвращает значение типа int:int
14.6.1. Инициализация члена, являющегося объектом класса
14.6.1. Инициализация члена, являющегося объектом класса Что произойдет, если в объявлении _name заменить C-строку на тип класса string? Как это повлияет на почленную инициализацию по умолчанию? Как надо будет изменить явный копирующий конструктор? Мы ответим на эти вопросы в
Переносимые копии
Переносимые копии Используйте значение по умолчанию, переключатель -transportable, если вы работаете в многоплатформенном окружении. При этом данные записываются в межплатформенном стандартном формате external Data Representation (XDR)[151], позволяющем программе gbak читать файл на аппаратной
Теневые копии
Теневые копии Концепция, создание и поддержка теневых копий базы данных подробно обсуждались в главе 15. Утилита gfix имеет средства для работы с теневыми копиями. Активизация теневой копии Ключ для активизации теневой копии, когда база данных "умерла", -ac[tivate]. Синтаксис:gfix
Активизация теневой копии
Активизация теневой копии Ключ для активизации теневой копии, когда база данных "умерла", -ac[tivate]. Синтаксис:gfix -ас <путь-к-первому-тому-оперативном-копии>Предположим, что первым томом теневой копии является employee.shl. Находится в каталоге /opt/dbshadows. Вы можете активизировать
5.4.2 Уточнение* Имени Члена
5.4.2 Уточнение* Имени Члена – * Иногда называется также квалификацией. (прим. перев.)Иногда полезно делать явное различие между именами члнов класса и прочими именами. Для этого используется операция ::, «разрешения области видимости»:class x (* int m; public: int readm() (* return x::m; *) void setm(int
5.4.2 Уточнение* Имени Члена
5.4.2 Уточнение* Имени Члена – * Иногда называется также квалификацией. (прим. перев.)Иногда полезно делать явное различие между именами члнов класса и прочими именами. Для этого используется операция ::, «разрешения области видимости»:class x (* int m; public: int readm() (* return x::m; *) void setm(int
Алексей Стародымов Logitech: необычная гарантия
Алексей Стародымов Logitech: необычная гарантия На дешевую компьютерную периферию никакая гарантия, как правило, не предоставляется: если вы приобретете безымянную клавиатуру за десять долларов, а потом в процессе эксплуатации y неё перестанет работать половина клавиш, вам,
Принцип единственности цели
Принцип единственности цели Чем так замечателен вызов компонента? В конце концов, каждый программист знает, как написать процедуру translate, которая перемещает точку на заданное расстояние. Традиционная форма вызова, доступная с незначительными вариациями во всех языках