From: Rob Stewart (stewart_at_[hidden])
Date: 2005-04-28 12:36:52
From: Jason Hise <chaos_at_[hidden]>
> Based on the recent discussions involving pointer container copyability,
> I thought I might want to get some opinions about a similar design
> decision made in singleton.
> The singleton provides a smart pointer to access the instance, which
> does locking, null state detection, and possibly recreation under the
> covers when operator -> is used. As a result, it would be comparatively
> unsafe to use a raw pointer or a straight reference to the singleton
> instance, which can do none of these checks when being used to access a
> member of the singleton. Because of this, I did not provide an
> overloaded unary * operator for the singleton pointer class. However,
> there might be times when the singleton needs to be used polymorphically
> as some other base class or interface, and in such cases the only way to
> manage this is with a raw pointer or reference. Thus I currently
> provide a member function get_unsafe_ptr which actually returns a raw
> pointer to the instance.
> Should I provide an operator * to return an 'unsafe reference', or add a
> function like get_unsafe_reference(), which forces the programmer to
> consider carefully before calling it? Should I add neither, and only
> leave get_unsafe_ptr? Are there cases in which the non-standard
> spelling of 'get a reference from the pointer' could cause problems?
As I understand it, the operation is inherently unsafe; it isn't
a matter of efficiency, or even desirable usage. Given that, it
is most appropriate that you spell things differently. You want
to call attention to such usage.
Having said that, is it really the case that operator *()
couldn't do the same work as operator ->() (possibly adding an
exception if you can't get the underlying object)?
Assuming you still don't provide operator *(), or you also want
the raw semantics of your get_unsafe_*() function(s), I wonder if
cast notation wouldn't be even better (versus providing access as
a public member function):
T * q(unsafe<T *>(p));
T & r(unsafe<T &>(p));
That is, unsafe() (whatever you might call it) would always take
a singleton pointer, but depending upon whether it was
parameterized to get a pointer or reference would do something
-- Rob Stewart stewart_at_[hidden] Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk