سؤال

I'd like to know if there is any smart pointer type concept that implements the "very weak reference" idea.

This would be basically a weak_ptr but that cannot be turned into a shared_ptr, basically, when you have very_weak_refs out-there, you are sure that the strong-ref count can never go up.

This would allow better "strong ownership" of memory by managers, and delivering very weak references in the wild would still allow clients to access the data by using good old raw pointer through a .lock_get() function or equivalent... (name designed to mirror what you would have doing .lock().get() usually).

You don't have the same security on data, because your object may be destroyed while you use it, but if your environment is controlled enough so that you know that the manager's cannot clean its data while you are processing, you're still good to use raw-pointers locally after having checked against null_ptr after lock_get().

Do any of you wished for similar thing, more info/intelligence/thoughts on that ? thanks.

rationale : the motivation behind is that weak_ptr has the "security flaw" of being turnable to shared and therefore, after distributing weak references in the wild, you basically did the same than distributing shared ones because anybody can keep very long lived shared refs on your data effectively preventing correct cleaning by the entities that were suppsed to be strong (the manager).

This is solved by very-weak-refs, when you distribute that kind of objects in your manager's public interface, you are sure that when you delete your last shared ref, your data is deleted.

For me, the whole concept of weak references works only with well behaved clients; who understands that they should promotes their weak refs into shareds for only small amounts of time.

هل كانت مفيدة؟

المحلول

Unfortunately, what you are asking for is impossible with the traditional interface of smart pointers.

The issue is one of lifetime. A weak_ptr cannot be use to access the object directly, because it does not guarantee that said object will live long enough: the object might be pulled right from under your feet.

Example:

int main() {
    std::shared_ptr<int> sp(new int(4));
    std::weak_ptr<int> wp(sp);

    if (not wp.expired()) {
        sp.reset();
        std::cout << *wp << "\n"; // Access WP ? But there is nothing there!
    }
}

Thus, for better or worse, there is no other choice than recovering a shared pointer from the weak pointer any time you actually need to access the object without controlling the duration of this access.


This last point, however, is our clue. A simple idea being to write a well-behaved client of weak_ptr yourself and change the way it allows the external world to access the data. For example:

template <typename T>
class very_weak_ptr {
public:
    very_weak_ptr() {}

    explicit very_weak_ptr(std::weak_ptr<T> wp): _wp(wp) {}

    template <typename F>
    void apply(F&& f) {
        std::shared_ptr<T> sp = _wp.lock();
        f(sp.get());
    }

private:
    std::weak_ptr<T> _wp;
}; // class very_weak_ptr

Note: there is one remaining flaw, enable_shared_from_this allows to recover a std::shared_ptr<T> from the very instance of T; you can add a compile time check on T to prevent usage of this class with such objects.

نصائح أخرى

What you ask for is functionally equivalent to, starting with a std::shared_ptr<>:

  • initially creating a std::weakptr<> thereto + .get()-ting a raw pointer,
  • before use of the raw pointer, checking the weak_ptr<> hasn't .expired().

Do any of you wished for similar thing, more info/intelligence/thoughts on that ? thanks.

No... if you need to check the weak_ptr<>.expired() anyway, you might as well get a valid shared_ptr<>. What do you really think this is going to achieve? 'Better "strong ownership"' when you know somehow / require that the manager can't release the object during the period you're using the raw pointer - doesn't add up....

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top