Я пытаюсь сохранить глобальный список экземпляров определенного (базового) класса, чтобы я мог отследить их, просматривая этот глобальный список в любое время.
Я считаю, что самый правильный способ решения этой проблемы — это навязчивый список. Я слышал, что с этими существами можно столкнуться, например, покопавшись в ядре Linux.
В ситуации, в которой я нахожусь, мне не нужны такие гарантии производительности, и использование навязчивых списков несколько усложнит для меня вопросы.
Вот что я получил, чтобы реализовать эту концепцию класса, который знает обо всех его экземплярах.
class A {
static std::forward_list<A*> globallist;
std::forward_list<A*>::iterator listhandle;
public:
A() {
globallist.push_front(this);
listhandle = globallist.begin();
}
virtual ~A() {
globallist.erase_after(...); // problem
}
};
Проблема в том, что нет forward_list::erase()
и это действительно не похоже на сохранение globallist.before_begin()
в ctor сделало бы мне много хорошего. Я никогда не должен разыменовывать before_begin()
итератор. Будет ли это на самом деле держаться за позицию? Если я спасу before_begin
итератор, а потом push_front()
новый элемент, этот итератор, вероятно, все еще не может быть разыменован, но будет ли он пригоден для отправки erase_after()
?
forward_list
это односвязный список Чтобы удалить узел в середине этого, вы должны каким-то образом иметь указатель на предыдущий узел. Например, вы можете сделать что-то вроде этого:
class A {
static std::forward_list<A*> globallist;
std::forward_list<A*>::iterator prev_node;
public:
A() {
A* old_head = globallist.front();
globallist.push_front(this);
prev_node = globallist.before_begin();
old_head->prev_node = globallist.begin();
}
};
Случай вставки первого элемента в пустой список, а также логика удаления оставлены для читателя в качестве упражнения (при удалении скопируйте prev_node
к следующему узлу prev_node
).
Или просто используйте std::list
и избежать всех этих неприятностей.
Других решений пока нет …