Is there any pointer-wrapper that would track if raw pointer was deleted?

Viewed 199

I am interacting with (not-owned-by-me) API that takes a raw pointer to Thing and sometimes deletes it on its own, basically something like:

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

Now I'm writing some tests that on a side interact with this method, and I would want to avoid writing typical T* ptr = new Thing(); bool res = foo(ptr); /* real test */; if (!res) { delete ptr; }; spread across the code.

So I've created some kind of "tracking-wrapper" that looks like this:

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);
};

so basically I can use it like this:

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

with Holder's destructor doing the cleanup of Thing* if necessary.

Is there any alternative for this custom code (e.g. in standard library)?

We can assume the following:

  • T's destructor is virtual,
  • T does not require arguments to be constructed,
  • we cannot modify T.
1 Answers
auto h = std::make_unique<T>();
if (foo(h.get())) {
   h.release(); // already deleted, so we don't own it
}

(And this is why implementations shouldn't mark unique_ptr::release as [[nodiscard]])

Related