8.4. Автоматическое добавление новых экземпляров класса в контейнер
8.4. Автоматическое добавление новых экземпляров класса в контейнер
Проблема
Требуется хранить все экземпляры класса в едином контейнере, не требуя от пользователей класса выполнения каких-либо специальных операций.
Решение
Включите в класс статический член, являющийся контейнером, таким как list, определенный в <list>. Добавьте в этот контейнер адрес объекта при его создании и удалите его при уничтожении. Пример 8.4 показывает, как это делается.
Пример 8.4. Отслеживание объектов
#include <iostream>
#include <list>
#include <algorithm>
using namespace std;
class MyClass {
protected:
int value_;
public:
static list<MyClass*> instances_;
MyClass(int val);
~MyClass();
static void showList();
};
list<MyClass*> MyClass::instances_;
MyClass::MyClass(int val) {
instances_.push_back(this);
value_ = val;
}
MyClass::~MyClass() {
list<MyClass*>::iterator p =
find(instances_.begin(), instances_.end(), this);
if (p != instances_.end()) instances_.erase(p);
}
void MyClass::showList() {
for (list<MyClass*>::iterator p = instances_.begin();
p != instances_.end(); ++p)
cout << (*p)->value_ << endl;
}
int main() {
MyClass a(1);
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.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Объект Object и использование его экземпляров
Объект Object и использование его экземпляров Но об одном встроенном объекте следует поговорить особо. Это объект Object, весьма специфический.Экземпляры этого объекта обычно используются для хранения сложных структур данных, включающих произвольный набор свойств и методов.
Автоматическое обновление
Автоматическое обновление Следующее важное звено в обеспечении безопасности Windows – автоматическое обновление. Ценность своевременной установки обновлений заключается в том, чтобы избежать атаки злоумышленников через уязвимости в операционной системе. Поскольку Windows
Объект Object и использование его экземпляров
Объект Object и использование его экземпляров Но об одном встроенном объекте следует поговорить особо. Это объект Object, весьма специфический.Экземпляры этого объекта обычно используются для хранения сложных структур данных, включающих произвольный набор свойств и методов.
Добавление новых элементов в панель элементов управления
Добавление новых элементов в панель элементов управления Чтобы получить возможность использовать элемент управления ActiveX, выполните следующее.1. Установите программное обеспечение элемента управления на жесткий диск.Мне кажется, это имеет смысл.2. Зарегистрируйте
76. По умолчанию используйте vector . В противном случае выбирайте контейнер, соответствующий задаче
76. По умолчанию используйте vector. В противном случае выбирайте контейнер, соответствующий задаче РезюмеОчень важно использовать "правильный контейнер". Если у вас есть весомые причины выбрать определенный тип контейнера, используйте тот контейнер, который наиболее
8.2.3. Доступ к парам ключ-значение и добавление новых пар
8.2.3. Доступ к парам ключ-значение и добавление новых пар В классе Hash есть методы класса [] и []=. Используются они почти так же, как одноименные методы в классе Array, но принимают лишь один параметр. В качестве параметра может выступать любой объект, а не только строка (хотя
11.2.10. Автоматическое определение методов чтения и установки на уровне класса
11.2.10. Автоматическое определение методов чтения и установки на уровне класса Мы уже рассматривали методы attr_reader, attr_writer и attr_accessor, которые немного упрощают определение методов чтения и установки атрибутов экземпляра. А как быть с атрибутами уровня класса?В Ruby нет
Вставка элемента в отсортированный контейнер
Вставка элемента в отсортированный контейнер Если необходимо создать отсортированный массив или связный список, у нас существует выбор того или иного метода поддержания порядка элементов. Можно сначала вставлять элементы в контейнер, а затем их сортировать и
6.4. Как определить последовательный контейнер?
6.4. Как определить последовательный контейнер? Для того чтобы определить объект контейнерного типа, необходимо сначала включить соответствующий заголовочный файл:#include vector#inclnde list#include deque#include map#include setОпределение контейнера начинается именем его типа, за которым в
5.2.3. Добавление элемента к списку, если он в нем отсутствует (добавление без дублирования)
5.2.3. Добавление элемента к списку, если он в нем отсутствует (добавление без дублирования) Часто требуется добавлять элемент X в список L только в том случае, когда в списке еще нет такого элемента. Если же X уже есть в L, тогда L необходимо оставить без изменения, поскольку
Создание экземпляров
Создание экземпляров Что же до экземпляров, то они создаются совсем просто. Достаточно вывести на экран панель Library, выбрать в списке образцов этой панели нужный образец и перетащить его на рабочий лист. На листе будет создан новый экземпляр выбранного нами образца