Если Ваши тесты не очень полны, Вы могли бы попасть в ложное чувство "всего, работает" просто, потому что Вы тестируете передачу. Теоретически, если Ваши тесты передают, код работает; но если бы мы могли бы записать коду отлично первый раз, когда нам не были бы нужны тесты. Мораль здесь должна удостовериться, что сделала проверку работоспособности самостоятельно прежде, чем назвать что-то завершенным, только полагайтесь на тесты.
На той ноте, если Ваша проверка работоспособности находит что-то, что не тестируется, удостоверьтесь, что возвратились и записали тест для него.
Вы можете использовать член lock ()
из boost :: weak_ptr
, чтобы быть возможность протестировать (затем использовать) значение weak_ptr
без обработки исключений.
Это обычная вещь в разработке игр. Обычно используется система дескрипторов объектов, а не слабые указатели Boost, потому что нам нужна базовая таблица поиска, чтобы быть постоянной памятью, и потому что иногда нам нужна дополнительная информация или гарантии, которых Boost не получил.
Обычный подход - использовать уточнение указателей на указатели. На объект ссылаются по дескриптору, а не по указателю. Дескриптор - это индекс в большом массиве указателей на сущности. Когда объект умирает, он обнуляет указатель в своей таблице объектов.
struct handle_t
{
uint32 serialnumber; // this is a GUID for each entity; it increases
// monotonically over the life of the process
uint entityindex;
inline Entity *Get();
}
struct entityinfo_t
{
Entity *pEntity; // an entity's destructor NULLs this out on deletion
uint32 serialnumber;
}
entityinfo_t g_EntityTable[MAX_ENTITIES];
Entity *handle_t::Get()
{
entityinfo_t &info = g_EntityTable[entityIndex];
if ( serialnumber == info.serialnumber )
{
return info.pEntity;
}
else
{
return NULL;
}
}
Серийный номер необходим, потому что массив имеет постоянный размер - в конечном итоге вам нужно будет повторно использовать записи таблицы объектов, и есть вероятность, что вы можете сохранить дескриптор, скажем, индекса # 743, достаточно долго, чтобы объект был удален, а ячейка № 743 повторно использовалась для чего-то еще. Если бы у вас был просто указатель на список указателей, вы бы получили дескриптор, указывающий на совершенно другой объект, а не на NULL. Итак, мы даем каждой сущности глобально уникальный номер и также сохраняем его в дескрипторе.
Конечно, вы можете использовать вектор std, карту, словарь или какую-либо другую структуру данных для таблицы сущностей, но наши требования обычно заключаются в постоянной памяти, согласованности кеша и абсолютной максимальной производительности (поскольку handle_t :: Get () вызывается тысячи раз за кадр).
мы даем каждой сущности глобальный уникальный номер и также сохраняем его в дескрипторе.Конечно, вы можете использовать вектор std, карту, словарь или какую-либо другую структуру данных для таблицы сущностей, но наши требования обычно заключаются в постоянной памяти, согласованности кеша и абсолютной максимальной производительности (поскольку handle_t :: Get () вызывается тысячи раз за кадр).
мы даем каждой сущности глобальный уникальный номер и также сохраняем его в дескрипторе.Конечно, вы можете использовать вектор std, карту, словарь или какую-либо другую структуру данных для таблицы сущностей, но наши требования обычно заключаются в постоянной памяти, согласованности кеша и абсолютной максимальной производительности (поскольку handle_t :: Get () вызывается тысячи раз за кадр).