首页 > 解决方案 > 是否有任何指针包装器可以跟踪原始指针是否被删除?

问题描述

我正在与(不是我拥有的)API 进行交互,该 API 需要一个原始指针Thing,有时会自行删除它,基本上是这样的:

bool foo(Thing* ptr) {
    if (/* some condition */) {
        delete ptr;
        return true;
    } else {
        return false;
    }
}

现在我正在编写一些与此方法交互的测试,并且我希望避免T* ptr = new Thing(); bool res = foo(ptr); /* real test */; if (!res) { delete ptr; };在代码中编写典型的传播。

所以我创建了某种看起来像这样的“跟踪包装器”:

template <typename T> class Holder {
public:

    // Subclass of Z where the dtor will just update Holder's state.
    template <typename Z> class Helper : public Z {
    public:
        Helper(Holder<Z>& holder): holder_{holder} {}
        virtual ~Helper() { holder_.markDeleted(); }

    private:
        Holder<Z>& holder_;
    };

    ~Holder() {
        if (!deleted_) { delete ptr; }
    }

    void markDeleted() { deleted_ = true; }
    T* data() { return ptr; }

private:
    bool deleted_ = false;
    T* ptr = new Helper<T>(*this);
};

所以基本上我可以这样使用它:

Holder<Thing> h;
foo(h.data());

Thing*如有必要,使用 Holder 的析构函数进行清理。

这个自定义代码有什么替代方法(例如在标准库中)?

我们可以假设如下:

标签: c++inheritancec++17destructor

解决方案


auto h = std::make_unique<T>();
if (foo(h.get())) {
   h.release(); // already deleted, so we don't own it
}

(这就是为什么实现不应该标记unique_ptr::release[[nodiscard]]


推荐阅读