Если объекты не ссылаются друг на друга, ручной подсчет ссылок может стоить попробовать.При добавлении в список или удалении из него будет больше затрат, но не будет никаких накладных расходов на фактический доступ к объекту(Это может быть болезненно для диагностики, когда вы ошибаетесь, поэтому я рекомендую быть осторожным, чтобы сделать это правильно.)
Если между операциями есть мертвое время, рассмотрите своего рода сборщик мусора.Вести список всех объектов (возможно, навязчивый список).Если у вас есть время сэкономить, сделайте перекрестную ссылку на другие списки;любые объекты, которых нет в списке, могут быть удалены.Для этого вам не нужен дополнительный массив (только глобальный счетчик и последний увиденный счетчик для каждого объекта), поэтому он может быть достаточно эффективным.
Другой вариант - использовать интеллектуальный указатель, который обеспечиваетдоступ к базовому указателю.Если вы пытаетесь избежать чрезмерной нагрузки на перегруженный operator->
, то, возможно, стоит попробовать.Сохраняйте умные указатели в списках (это делает управление временем жизни для вас), а затем при работе с объектами вы можете получить необработанный указатель для каждого из них и работать с ним (таким образом, вы не несете издержек при перегрузке operator->
так далее.).Например:
std::vector<smart_ptr<T> > objects;
if(!objects.empty()) {
smart_ptr<T> *objects_raw=&objects[0];
for(size_t n=objects.size(),i=0;i<n;++i) {
T *object=objects_raw[i].get_ptr();
// do stuff
}
}
Такой подход я предпочитаю лично.Долгосрочное хранение получает умный указатель, краткосрочное хранение получает простой указатель.Временами жизни объекта легко управлять, и вы не потеряете 1 000 000 крошечных накладных расходов (это более важно для поддержания работоспособности отладочной сборки, чем для сборки выпуска, но, тем не менее, она может легко добавить потраченное время).