]> sigrok.org Git - libsigrok.git/commitdiff
C++: Fix duplicated shared_ptr creation.
authorMartin Ling <redacted>
Tue, 2 Sep 2014 18:21:11 +0000 (19:21 +0100)
committerBert Vermeulen <redacted>
Tue, 2 Sep 2014 19:33:47 +0000 (21:33 +0200)
bindings/cxx/include/libsigrok/libsigrok.hpp

index 35b3d441fd6fd9df91f5487a458ce3b04dc43b78..ca9c119befa16f7a64ee2ac4d5a34f5e6be7f8ec 100644 (file)
@@ -125,8 +125,7 @@ public:
 };
 
 /* Base template for most classes which wrap a struct type from libsigrok. */
-template <class Parent, typename Struct> class SR_API StructureWrapper :
-       public enable_shared_from_this<StructureWrapper<Parent, Struct> >
+template <class Parent, typename Struct> class SR_API StructureWrapper
 {
 protected:
        /*  Parent object which owns this child object's underlying structure.
@@ -144,24 +143,41 @@ protected:
                references to both the parent and all its children are gone. */
        shared_ptr<Parent> parent;
 
+       /* Weak pointer for shared_from_this() implementation. */
+       weak_ptr<StructureWrapper<Parent, Struct> > weak_this;
+
 public:
+       /* Note, this implementation will create a new smart_ptr if none exists. */
+       shared_ptr<StructureWrapper<Parent, Struct> > shared_from_this()
+       {
+               shared_ptr<StructureWrapper<Parent, Struct> > shared;
+
+               if (!(shared = weak_this.lock()))
+               {
+                       shared = shared_ptr<StructureWrapper<Parent, Struct> >(
+                               this, reset_parent);
+                       weak_this = shared;
+               }
+
+               return shared;
+       }
+
        shared_ptr<StructureWrapper<Parent, Struct> >
-       get_shared_pointer(Parent *parent)
+       get_shared_pointer(shared_ptr<Parent> parent)
        {
                if (!parent)
                        throw Error(SR_ERR_BUG);
-               this->parent = static_pointer_cast<Parent>(parent->shared_from_this());
-               return shared_ptr<StructureWrapper<Parent, Struct> >(
-                       this, reset_parent);
+               this->parent = parent;
+               return shared_from_this();
        }
+
        shared_ptr<StructureWrapper<Parent, Struct> >
-       get_shared_pointer(shared_ptr<Parent> parent)
+       get_shared_pointer(Parent *parent)
        {
                if (!parent)
                        throw Error(SR_ERR_BUG);
-               this->parent = parent;
-               return shared_ptr<StructureWrapper<Parent, Struct> >(
-                       this, reset_parent);
+               return get_shared_pointer(static_pointer_cast<Parent>(
+                       parent->shared_from_this()));
        }
 protected:
        static void reset_parent(StructureWrapper<Parent, Struct> *object)