From -8649371033562208932 X-Google-Thread: f78e5,49ee1c3b487069d X-Google-Attributes: gidf78e5,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!news3.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!local01.nntp.dca.giganews.com!nntp.speakeasy.net!news.speakeasy.net.POSTED!not-for-mail NNTP-Posting-Date: Wed, 20 Dec 2006 22:30:11 -0600 Return-Path: X-Authentication-Warning: mulga.csse.unimelb.edu.au: fjh set sender to devnull@stump.algebra.com using -f X-Robomod: STUMP, ichudov@algebra.com (Igor Chudov) X-Original-To: std-c++@mailman.ucar.edu Delivered-To: std-c++@mailman.ucar.edu From: "Lance Diduck" Newsgroups: comp.std.c++ Subject: Re: What is the rationale behind std::tr1::enable_shared_from_this? Organization: http://groups.google.com Message-ID: <1166673135.120245.47070@79g2000cws.googlegroups.com> References: <1166035229.485959.60700@16g2000cwy.googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" X-Complaints-To: groups-abuse@google.com User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727),gzip(gfe),gzip(gfe) Complaints-To: groups-abuse@google.com Injection-Info: 79g2000cws.googlegroups.com; posting-host=24.193.88.8; posting-account=3mYY3wwAAADRamnjcYfRKWdoFpb0mshK X-Virus-Scanned: amavisd-new at ucar.edu X-Virus-Scanned: amavisd-new at csse.unimelb.edu.au Approved: Fergus Henderson , moderator of comp.std.c++ X-Virus-Scanned: amavisd-new at csse.unimelb.edu.au Date: Wed, 20 Dec 2006 22:24:06 CST Lines: 137 NNTP-Posting-Host: 65.182.171.162 X-Trace: sv3-gFi41T5gYIEsv9e8uVMMlrqX01pQcwMLxtbgMPxDmwMXrOonQIJhTzTV8e9en8j4IK5xSD9G/unyWWS!n6uneOvLT3qFPBHjw+Dc/HZClGuZYRdSQlMJ/y6ROBi/4xvjmJouMeX90k3u2PHHbftgOd5ic624!IC2ADD+k+gtjdGhU/cJ1JjkVL82cl7BkwBuZXy8y X-Complaints-To: abuse@speakeasy.net X-DMCA-Complaints-To: abuse@speakeasy.net X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly X-Postfilter: 1.3.32 Xref: g2news2.google.com comp.std.c++:5115 A regular "reference counted shared pointer" only allows an acyclic dependency graph. This is fairly common knowledge. If we need cyclic references, such as back pointers in a tree type graph (like a file hierarchy -- all directories have a reference to their entries, and all entries have a reference to their directory. This is cyclic) or a doubly linked list. In this case we would use a shared_ptr in one direction, and a weak_ptr for the other . There is no apriori preference which is better to use in which "direction." Either way is fine, as long as it is consistent for your project. To the point: There are many cases where we would want a reflexive dependency graph. In other words, an object can issue its own shared_ptr. This is the semantic "whatever shared_ptr manager owns me, give me a shared_ptr attached to him." This is EXTREMELY useful in a design where a single object implements multiple interfaces. i.e struct Interface2{}; struct Interface1{ virtual tr1::shared_ptr get()=0; }; //a factory for interface 1 tr1::shared_ptr make(int a){ if (a)//first choice return shared_ptr(new Impl); //else return shared_ptr(new Impl2); } //the implementations, hidden from user class Impl:Interface2,Interface1, tr1::enable_shared_from_this{ friend shared_ptr make(int);//factory pattern Impl(){} public: tr1::shared_ptr get(){ return shared_from_this(); } }; //without enable_shared_from_this, we need separate classes class Privateimpl:Interface2{ friend class Impl2; Privateimpl(){} }; class Impl2:Interface1,tr1::enable_shared_from_this{ friend shared_ptr make(int);//factory pattern Impl2(){} public: tr1::shared_ptr get(){ return tr1::shared_ptr(new Privateimpl); } }; /////CLIENT CODE//// shared_ptr first(make(1)); shared_ptr second=make(0); shared_ptr third=second->get(); shared_ptr fourth=first->get(); //does not matter how underlying implementation is implemented Many class hierarchy designers familiar with Java, COM or other like it will be very at home with this style. The point is that the class implementor in free to use MI to implement interfaces, which has long been a tried and true approach "Intrusive pointers" have this same property, with the added benefit that the shared_ptr does not have to be constructed from the complete type, but the disadvantage that every class has to inherit from the same object manager interface. I personally prefer intrusive style. Gotcha!!! You asked Calling shared_from_this() inside a constructor struct Parent; struct Child{ shared_ptr p; Child(shared_ptr _p):p(_p){ if(/*something*/)throw 1; } }; struct Parent:enable_shared_from_this{ weak_ptr c; Parent(){ shared_ptr d(new Child(shared_from_this()); c=weak_ptr(d); } }; This does not work no matter how you try it. A ref counted shared pointer, intrusive or non,needs to manage a completely constructed object. Basically the above translates to shared_ptr _tmp(this); and if Child happened to throw, _tmp tries to delete an object that was never constructed. That is bad, and there is no workaround. The child objects have to get info about the Parent after Parent has been fully constructed Others 1.Deriving from a class that derives from enable_shared_from_this. I'm sure the docs say somewhere that must be the complete --i.e most derived-- type. If they don't they need to. 2. Sometimes legacy shared_ptr that do not support weak_ptr semantics are facelifted to look like tr1::shared_ptr as much as they can. Intrusive style pointers can be made to have the same semantics as enable_shared_from_this, however non-intrusive will require far more machinery. Hope this helps Javier wrote: > I'm trying to find the rationale behind this class beyond the Boost > documentation > (http://www.boost.org/libs/smart_ptr/sp_techniques.html#from_this) and > Pete Becker's C++ Standard Library Extensions book (section 2.6, pp > 57). > > I understand the technicalities of the class, but what are some > practical uses? Are there any "gotchas"? It would seem to me that > once a class is "smartified" there are implications in a design > regarding its lifetime. > > Regards, > > Javier > > --- > [ comp.std.c++ is moderated. To submit articles, try just posting with ] > [ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ] > [ --- Please see the FAQ before posting. --- ] > [ FAQ: http://www.comeaucomputing.com/csc/faq.html ] --- [ comp.std.c++ is moderated. To submit articles, try just posting with ] [ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.comeaucomputing.com/csc/faq.html ]