LINUX.ORG.RU

Совет по дизайну

 , ,


0

1

Привет. Есть такой код:

class A {
// some stuff happens here
};

class B {
...
int active;
std::list<A> myList;
};

Есть список объектов myList. Нужно, чтобы они изменяли количество активных объесктов (active) в классе, в котором находится список. Пока навскидку пара вариантов

  • Передать каждому объекту А указатель на В, а в В добавить методы инкремента/декремента активных объектов.
  • Заюзать сигналы/слоты буста, также добавив методы инкремента/декремента.
  • ?

Что посоветуете?

★★★★★

Последнее исправление: beastie (всего исправлений: 1)

Я бы прикрутил паттерн Observer. Не знаю про Boost, может его сигналы/слоты как раз для этого и предназначены. Ну и надеюсь, что это всё будет выполняться в однопоточной среде, иначе active придется атомарной делать.

CARS ★★★★
()
Последнее исправление: CARS (всего исправлений: 1)

Нужно, чтобы они изменяли количество активных объесктов (active) в классе, в котором находится список

Не-не нужно несколько иное - знать количество активных объектов. И тут есть ещё вариант спрашивать у объект, активен ли он.

Твой вариант 1 совсем плох, и active должна быть атомарной, и повысится связанность классов A и B. Твой вариант 2 лучше, т.к. остаётся только требование атомарности active. Мой вариант (ИМХО) самый простой и требует только потокобезопасности функции bool A::isActive() const, которая и так в виду константности должна быть потокобезопасной. Так что тебе надо ответить на вопрос - насколько часто изменяется активность объектов и насколько часто требуется количество активных объектов и учесть требования к производительности этих классов.

Begemoth ★★★★★
()
Последнее исправление: Begemoth (всего исправлений: 1)
Ответ на: комментарий от Begemoth

Мой вариант (ИМХО) самый простой и требует только потокобезопасности функции bool A::isActive() const, которая и так в виду константности должна быть потокобезопасной. Так что тебе надо ответить на вопрос - насколько часто изменяется активность объектов и насколько часто требуется количество активных объектов и учесть требования к производительности этих классов

Я думал над этим, но это будет подразумевать проход по всему списку, каждый раз (по крайней мере до нахождения первого активного). Пока объектов подразумевается 2-4 от силы, т.е. в данный конкретный момент это более или менее решение. Если количество объектов вырастет, то будет ой.

Думаю, так и сделаю.

UVV ★★★★★
() автор топика

Можно сделать свою обертку-контейнер, в рамках который применить первый вариант. Связанность классов и атомарность полностью скрываются в контейнере, на пользовательском уровне все будет выглядеть как обычно. Для пущей совместимость с stl можно воткнуть интерфейс итераторов.

Но я обычно делаю уже предложенный тут вариант active/inactive, а в момент прохода по списку выкидываю все inactive объекты. Навскидку производительность не должна отличаться от твоих двух вариантов.

staseg ★★★★★
()
Ответ на: комментарий от UVV

Если количество объектов вырастет, то будет ой.

Только если объекты не могут внутри себя хранить состояние активности, и его потребуется вычислять. А если isActive будет просто возвращать значение внутренней переменной, то вызов isActive может быть встроен (если класс A не полиморфен). Если использовать std::vector вместо std::list и хранить объекты A по значению (а не указатели), то ещё и кэш повысит производительность.

И, кстати, использовать std::list вместо std::vector стоит только по результатам профилирования.

Begemoth ★★★★★
()
Ответ на: комментарий от staseg

Но я обычно делаю уже предложенный тут вариант active/inactive, а в момент прохода по списку выкидываю все inactive объекты

Об этом я не подумал, точно. Можно сделать второй список, и из него выкидывать объекты по мере обработки. Спс.

UVV ★★★★★
() автор топика
Ответ на: комментарий от UVV

2-4 от силы, т.е. в данный конкретный момент это более или менее решение. Если количество объектов вырастет, то будет ой

ну ты же можешь примерно порядок знать?
100? 1000? 10^6?

invy ★★★★★
()
Ответ на: комментарий от invy

static unsigned int activeCount;

О, об этом я чё-то позабыл. Спасибо.

UVV ★★★★★
() автор топика
Ответ на: комментарий от CARS

Ну и надеюсь, что это всё будет выполняться в однопоточной среде, иначе active придется атомарной делать.

boost::signals2 многопоточный. он это сам разрулит без проблем. но у него есть другая проблема - он каждый раз проверяет в цикле все сигналы. так что если сигналов много - это жручая шняга.

в любом случае, если делать инкремент-декремент, то выносить их в методы класса (пусть даже хоть инлайновые). чтобы потом по всему коду эти обращения не вылавливать в случае необходимости внести изменения.

Iron_Bug ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.