lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] Reference member = shared_ptr


From: Vadim Zeitlin
Subject: Re: [lmi] Reference member = shared_ptr
Date: Fri, 29 Jan 2021 22:54:56 +0100

On Fri, 29 Jan 2021 18:58:08 +0000 Greg Chicares <gchicares@sbcglobal.net> 
wrote:

[organizing access to the cache]

GC> Strategically, I think the present way is fine: everything's
GC> a shared_ptr.

 Sorry, I could well be missing something, but I still don't see any real
need for shared pointers here. I.e. it seems to me that everything would
work in exactly the same way if you kept unique pointers in the cache and
just (const) references to them elsewhere. I'll assume the benefits of
using unique, rather than shared, pointers are well-known and there is no
need to re-enumerate them, so the question is: why do you think we need a
shared pointer, when the ownership is not shared at all and, according to
what you wrote, the object always belongs to the cache (which is its
_unique_ owner)?

GC> These product files are expensive to parse, but
GC> don't use much memory; there aren't very many of them (a few
GC> hundred at most); and lmi sessions may last hours, but not
GC> weeks--so we never have any reason to discard anything from
GC> the cache, except at program termination; thus, I see no
GC> reason to use weak_ptr here.

 Yes, definitely.

GC> Tactically, however, I'm not so sure about all the variations:
GC> 
GC>  - class BasicValues holds a
GC>     std::shared_ptr<product_data>       product_;
GC> 
GC> which seems fine (what could be more natural?);

 Using "product_data const&" would be more natural, of course.

GC>  - product_database::initialize() has a local const reference:
GC>     product_data const& p(*product_data::read_via_cache(f));
GC> 
GC> which seems fine because it's local (beware of the rather
GC> ill-chosen class names: product_database != product_data);
GC> 
GC>  - class product_verifier has a const-reference data member:
GC>     product_data     const& p_;
GC> 
GC> which seems...well, I dunno. I hesitated to do that, but
GC> then I reasoned that this refers to cached data that's never
GC> discarded, so it seems okay. But if we decide that's really
GC> okay, then should we hold a 'product_data const&' in the
GC> first example as well (class BasicValues), for uniformity?

 Yes, absolutely. And not only for uniformity, but to remove the need to
have a shared_ptr<> in the first place, which is a bigger gain.

GC> Or is initializing a reference member from a shared_ptr
GC> anathema?

 Why would it be? Using a dangling reference would be anathema, and one way
of avoiding it is to use shared pointers everywhere and never use
references (or raw pointers, even non-owning ones) at all. Another, and
IMHO better, way of avoiding it is to clearly define the ownership and
lifetime rules, as you did, by specifying that the objects are created and
owned by the cache and live until the program termination, and follow them.

 I.e. either we can rely on the objects having well-defined lifetime and
then we don't need shared pointers at all. Or we can't rely on this, e.g.
because the cache could be purged at any moment, and then we do need shared
pointers and must not use (non-local) references anywhere. But IMO it
doesn't make much sense to do something in the middle between the two
approaches.

 Please let me know if I misunderstood something,
VZ

Attachment: pgpxEe3bm1lIa.pgp
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]