Я только что сгорел из-за ошибки, частично из-за моего непонимания, а частично из-за того, что я считаю неоптимальным дизайном в нашей кодовой базе. Мне любопытно, как можно улучшить мое 5-минутное решение.
Мы используем объекты с пересчетом, где у нас есть объекты AddRef () и Release () для этих классов. Один конкретный объект является производным от объекта ref-count, но общая функция для получения экземпляра этих объектов (GetExisting) скрывает AddRef () внутри себя без объявления о том, что она это делает. Это требует выполнения Release в конце функционального блока, чтобы освободить скрытые ссылки, но разработчик, который не проверял реализацию GetExisting (), не знал бы об этом, и тот, кто забыл добавить Release в конце функция (скажем, во время безумной поры времени исправления ошибок) пропускает объекты. Это, конечно, был мой ожог.
void SomeFunction(ProgramStateInfo *P)
{
ThreadClass *thread = ThreadClass::GetExisting( P );
// some code goes here
bool result = UseThreadSomehow(thread);
// some code goes here
thread->Release(); // Need to do this because GetExisting() calls AddRef()
}
Итак, я написал небольшой класс, чтобы избежать необходимости в Release () в конце этих функций.
class ThreadContainer
{
private:
ThreadClass *m_T;
public:
ThreadContainer(Thread *T){ m_T = T; }
~ThreadContainer() { if(m_T) m_T->Release(); }
ThreadClass * Thread() const { return m_T; }
};
Так что теперь я могу просто сделать это:
void SomeFunction(ProgramStateInfo *P)
{
ThreadContainer ThreadC(ThreadClass::GetExisting( P ));
// some code goes here
bool result = UseThreadSomehow(ThreadC.Thread());
// some code goes here
// Automagic Release() in ThreadC Destructor!!!
}
Что мне не нравится, так это то, что для доступа к указателю потока мне нужно вызвать функцию-член ThreadContainer, Thread (). Есть ли какой-нибудь умный способ, которым я могу это очистить, чтобы он стал синтаксически красивее, или что-то подобное затеняет смысл контейнера и создает новые проблемы для разработчиков, незнакомых с кодом?
Спасибо.