MyClass b(10);
MyClass с(100);
MyClass::showList();
}
Пример 8.4 создаст следующий вывод.
1
10
100
Подход в примере 8.4 очень прост: используйте для хранения указателей на объекты static list
. При создании объекта его адрес добавляется в list
; при его уничтожении он удаляется. Здесь имеется пара важных моментов.
При использовании любых членов-данных типа static
их требуется объявлять в заголовочном файле класса и определять в файле реализации. Пример 8.4 весь находится в одном файле, так что здесь это не применимо, но помните, что переменную типа static
требуется определять в файле реализации, а не в заголовочном файле. За объяснением причин обратитесь к рецепту 8.5.
Вы не обязаны использовать член static
. Конечно, можно использовать глобальный объект, но тогда дизайн не будет таким «замкнутым». Более того, вам где-то еще придется выделять память для глобального объекта, передавать его в конструктор MyClass
и в общем случае выполнять еще целый ряд действий.
Помните, что совместное использование глобального контейнера, как в примере 8.4, не будет работать, если объекты класса MyClass
создаются в нескольких потоках. В этом случае требуется сериализация доступа к общему объекту через мьютексы. Рецепты, относящиеся к этой и другим методикам многопоточности, приведены в главе 12.
Если требуется отслеживать все экземпляры класса, можно также использовать шаблон фабрики. В целом это будет означать, что для создания нового объекта клиентский код вместо вызова оператора new должен будет вызывать функцию. За подробностями о том, как это делается, обратитесь к рецепту 8.2.
Рецепт 8.2.
8.5. Гарантия единственности копии переменной-члена
Имеется переменная-член, у которой должен быть только один экземпляр независимо от числа создаваемых экземпляров класса. Этот тип переменных-членов обычно называется статическими членами или переменными
Объявите переменную-член с ключевым словом static
, затем инициализируйте ее в отдельном исходном файле (но не в заголовочном файле, где она объявлена), как показано в примере 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
. Это достаточно просто: добавьте это ключевое слово в заголовок класса, находящийся в заголовочном файле
protected:
static int count;
После этого требуется определить эту переменную в исходном файле. При этом для нее будет выделена память. Это делается с помощью указания полного имени переменной и присвоения ей значения, как здесь.
int OneStatic::count = 0;
В примере 8.5 я поместил это определение в файл