template <unsigned long long Rnd>
class DangleCanary {
public:
DangleCanary() noexcept { value = rightCanary(); }
~DangleCanary() noexcept { value = 0; }
DangleCanary(const DangleCanary&) noexcept {}
DangleCanary& operator=(const DangleCanary&) noexcept { return *this; }
void checkCanary() const;
private:
std::atomic<uintptr_t> value = 0;
uintptr_t rightCanary() const noexcept;
static constexpr auto SCRAMBLE = static_cast<uintptr_t>(Rnd);
};
template <unsigned long long Rnd>
uintptr_t DangleCanary<Rnd>::rightCanary() const noexcept
{ return reinterpret_cast<uintptr_t>(this) ^ SCRAMBLE; }
template <unsigned long long Rnd>
void DangleCanary<Rnd>::checkCanary() const
{
if (value != rightCanary())
throw std::logic_error("[DangleCanary] Dangling link detected!");
}
Как вы понимаете, это простенький код для проверки, что данный объект существует и указатель на него не «повис в воздухе». Подобные штуки используются, когда имеем дело с тупыми указателями, проходящими через плохо контролируемую среду (QAbstractItemModel — ну или просто код, написанный неопытным прогером).
Меня конкретно интересует деструктор: может ли он «заоптимизировать» присваивание value = 0, убив весь смысл детектора висячего указателя?