
Hello Boost-Users CAVEAT The attached code "works" but has a major design flaw regarding pointer conversion safety -- one which can currently either be accepted (at your risk) or rectified by limiting usage to one-hop inheritance. In particular, statement [3] (see below) is processed without complaint in unsafe mode -- when it should ideally provoke a compile-time error. Indeed, providing a general type-safe solution is not without challenge (read: my knowledge of C++ has been exhausted). If interested, member function 'Common::reVamp' would be a good place to start. PROBLEM I recently needed a 'shared_ptr' that could be globally reset -- that is, any one of the owners of the controlled resource could unilaterally replace that resource for the benefit (perhaps) of everyone else. This has been named "global_reset" in previous postings -- but I have adopted the shorter word "revamp". Moreover, it would be useful if this newly conceived "assign_ptr" could mimic the behavior of 'shared_ptr', whilst simultaneously providing the additional functionality. In particular, implicit upcasting should be maintained. This lead me to quickly reject options like: shared_ptr<scoped_ptr<Resource> > ptrPtrResource; And instead try to implement something like: assign_ptr<T> py(new Y()); My environment is single-threaded and issues like CPU cycles and memory consumption are not significant. Of more importance to me was coding at a high level -- in part, because I imagined that any conforming solution could subsequently be refactored to improve on performance and safety. SOLUTION STRATEGY The proposed solution has parallels with the Observer pattern and relies on 'shared_ptr' to do most of the work. Notwithstanding the code is now considerably more involved than I had originally envisaged. The biggest challenge was getting a multi-step inheritance chain to play ball with the semantics and syntax. Consider, if you would: class A; // base class class B : public A; class C : public B; // and perhaps more assign_ptr<B> b(new C()); // C resource held by B pointer [1] assign_ptr<A> a = b; // resource now also held by A pointer a.revamp(new C()); // not so simple to implement [2] The statement marked [2] looks reasonable. But it offers my observer class a challenge -- namely the need to have available the type information present during statement [1] when re-assigning the replacement resource to 'b' during the 'revamp' call. In addition, the following statement should fail in some way -- ideally at compile-time: a.revamp(new A()); // okay for 'a', nonsensical for 'b' [3] The following member functions are offered, noting that the first two are already part of 'shared_ptr:' a.use_count() // number of owners in the pool a.unique() // true if use_count() == 1 a.revamp_count() // number of revamps a.original() // true if revamp_count() == 0 a.external_count() // number of owners outside the pool a.exclusive() // true if external_count() == 0 PRIOR DISCUSSIONS The problem itself is noted in the Boost documentation: Boost Libraries + Smart Pointers + shared_ptr class template + Smart Pointer Programming Techniques + Obtaining a shared_ptr from a raw pointer One significant thread on this topic can be found at: subject = shared_ptr and global reset date = Feb-2009 http://thread.gmane.org/gmane.comp.lib.boost.user/45032/focus=45034 CODE A single *.cc file is attached. This code was developed using: boost : 1.39.0 (built from source) compiler : GCC g++ 4.1.2 (2006) kernel : Ubuntu 6.10 Linux 2.6.17-12-generic hardware : 1.4GHz Intel Celeron M / 512MiB RAM DESIGN SUMMARY This section gives a brief outline of the design thinking I used. Note too that the code is also extensively documented. The point-of-entry is class template 'assign_ptr'. This holds its own controlled resource pointer, just like 'shared_ptr', but in this case, as a 'shared_ptr'. It also holds a 'shared_ptr' to a class 'Common' object (aka "Subject" under the Observer pattern). Class 'Common' manages a list of its 'Client's (aka "Observers") and, in doing so, defines the pool. The derived class template 'ClientImp' duly retains the type of its associated 'assign_ptr'. The various 'assign_ptr' member functions pass requests to the 'Common' object, which responds accordingly. Most of these member functions were declared above. Class 'Common', in turn, contains the management functions 'attach' and 'detach' and the interventionist function 'reVamp'. The remainder of the 'assign_ptr' implementation is aimed at providing a similar interface to 'shared_ptr'. Finally, everything is placed in namespace 'xeona'. LITERATURE Alexandrescu (2001, ch7, pp157-195) devotes a chapter to smart pointers and the underlying design trade-offs -- however "revamping" is not considered: Alexandrescu, Andrei. 2001. Modern C++ design : generic programming and design patterns applied. Addison-Wesley, Boston, USA. ISBN 0-201-70431-5. The notion of "revamping" is never far away in Meyers (1996 item29 pp183-213) reference counting example, but neither is it directly mentioned. Meyers, Scott. 1996. More effective C++ : 35 new ways to improve your programs and design. Addison-Wesley, Boston, USA. ISBN 0-201-63371-X. Some ideas regarding the use of Boost.Any came from the following book (which I found both instructional and nicely written): Karlsson, Bjoern. 2006. Beyond the C++ Standard Library : an introduction to Boost. Addison-Wesley, Upper Saddle River, New Jersey, USA. ISBN 0-321-13354-4. The following web article offered some insights on solutions: Becker, Thomas. 2007. On the tension between object-oriented and generic programming in C++ : and what type erasure can do about it. C++ Source. [http://www.artima.com/cppsource/type_erasure1.html] Finally, Dattatri (2002 pp487-496) provides an implementation of counted pointers and discusses the design issues in some depth. Dattatri, Kayshav. 2002. C++ : effective-object oriented software construction : concepts, principles, industrial strategies and practices -- Second edition. Prentice Hall PTR, Upper Saddle River, New Jersey, USA. ISBN 0-13-086769-1. ABOUT THE AUTHOR I am a PhD student writing a policy-oriented energy system simulation at the Institute for Energy Engineering (IET), Technical University of Berlin (TU-Berlin), Germany. I have never coded professionally, but consider myself reasonably competent in terms of scientific programming. --- I am happy to take comments, suggestions, and patches and will post an update in due course. Please note that I will be checking my email only infrequently over the next four weeks or so. best wishes to all Robbie Morrison --- PhD student -- policy-oriented energy system simulation Technical University of Berlin (TU-Berlin), Germany University email (redirected) : morrison@iet.tu-berlin.de Webmail (preferred) : robbie@actrix.co.nz [from IMAP client]