Smart Pointer Question

V

Vijai Kalyan

I have been thinking about this and it may have already been thrashed
out and hung out to dry as a topic of no more interest but here goes.

I found when implementing a smart pointer that the typical
implementation goes like:

template<typename T>
class SmartPointer
{
// other stuff

T* operator->() const;
};

Now, when we pass around such a pointer in the following form:

void foo(const SmartPointer<X>& ptr)
{
ptr->Function1();
}

Function1() can be a function that can change the state of the
underlying object. Being a reference ptr of course cannot be
reassigned. Consequently, since we are looking at a "pointer" albeit a
smart one, we may want to actually implement the smart pointer as
follows:

template<class T,
class TMutableInterface = T
class TImmutableInterface = T>
class SmartPointer
{
// other stuff

TMutableInterface* operator->();
TImmutableInterface* operator->() const;
}

This has the following effect:

For "const SmartPointer<X, XMI, XImI>& ptr"

ptr->Function1() will only be allowed if Function1() is specified by
the "ImmutableInterface of X" that is "XImI".

and for "SmartPointer<X, XMI, XImI>& ptr"

ptr->Function2() will only be allowed if Function2() is specified by
the "MutableInterface of X" that is "XMI".

Thus in effect:

const SmartPointer<T, TMI, TImI>& ptr <=> T const* const ptr

and

SmartPointer<T, TMI, TImI>& ptr <=> T const* ptr

-------

I wonder if this has ever been explored? If so, can someone tell me how
they used it? I have been writing some utilities as part of my work,
where I find it useful to return a "const SmartPointer&" and
"SmartPointer&" depending on what access I want the caller to have.

Comments?

-vijai.
 
G

Gianni Mariani

Vijai said:
I have been thinking about this and it may have already been thrashed
out and hung out to dry as a topic of no more interest but here goes.

I found when implementing a smart pointer that the typical
implementation goes like:


NOTE I CHANGED THE NAMES TO SmartPointerA and SmartPointerB
template<typename T>
class SmartPointerA
....
template<class T,
class TMutableInterface = T
class TImmutableInterface = T>
class SmartPointerB
{
// other stuff

TMutableInterface* operator->();
TImmutableInterface* operator->() const;
}


Are these two equivalent ?

SmartPointerA<TIM> x ReturnConst()

const SmartPointerB<T,TM,TI> x ReturnConst()

Would that mean that SmartPointerB is far more verbose for no good reason ?

Does this also mean that you tie the constness of the smart pointer to
the accessibility of the object being pointed to which really should be
2 separate things ?

G
 
M

mlimber

Vijai said:
I have been thinking about this and it may have already been thrashed
out and hung out to dry as a topic of no more interest but here goes.

I found when implementing a smart pointer that the typical
implementation goes like:

template<typename T>
class SmartPointer
{
// other stuff

T* operator->() const;
};

Now, when we pass around such a pointer in the following form:

void foo(const SmartPointer<X>& ptr)
{
ptr->Function1();
}

Function1() can be a function that can change the state of the
underlying object. Being a reference ptr of course cannot be
reassigned. Consequently, since we are looking at a "pointer" albeit a
smart one, we may want to actually implement the smart pointer as
follows:

template<class T,
class TMutableInterface = T
class TImmutableInterface = T>
class SmartPointer
{
// other stuff

TMutableInterface* operator->();
TImmutableInterface* operator->() const;
}

This has the following effect:

For "const SmartPointer<X, XMI, XImI>& ptr"

ptr->Function1() will only be allowed if Function1() is specified by
the "ImmutableInterface of X" that is "XImI".

and for "SmartPointer<X, XMI, XImI>& ptr"

ptr->Function2() will only be allowed if Function2() is specified by
the "MutableInterface of X" that is "XMI".

Thus in effect:

const SmartPointer<T, TMI, TImI>& ptr <=> T const* const ptr

and

SmartPointer<T, TMI, TImI>& ptr <=> T const* ptr

-------

I wonder if this has ever been explored? If so, can someone tell me how
they used it? I have been writing some utilities as part of my work,
where I find it useful to return a "const SmartPointer&" and
"SmartPointer&" depending on what access I want the caller to have.

Comments?

The trick here is that you are transferring the constness of the
pointer to the pointee, which is a feature some have objected to
because it doesn't match the behavior of raw pointers (TR1/Boost's
smart pointers, for instance, are as close to raw pointers as possible
and don't support transferring the constness). However, that behavior
does match std::vector, which, as a "smart array" of sorts, diverges
from the behavior of raw arrays at the point of constness.

You'll need to watch out for copying to get rid of const, but your
policy-based pointer may take care of that automatically depending on
its copy constructors and assignment operators. In particular,
consider:

struct A { void Mutate(); }

void Foo( const SmartPointer<A,A,const A>& ptr )
{
ptr->Mutate(); // Error!

SmartPointer<A>& backDoor( ptr ); // Error?
backDoor->Mutate(); // No error here
}

Does SmartPointer<A> accept SmartPointer<A,A,const A> for copying?

If you disable copy constructors and assignment operators altogether by
making them private, undefined functions, then SmartPointer can't be
used in standard containers, which is a major drawback (one that
TR1/Boost's smart pointers avoids).

I have used this same technique for smart pointers that are members of
a class, so that if the class is const, the pointees become const also.
This behavior is not *always* desirable, but I find that it is
*usually* what I want and, as with std::vector, the compiler can more
closely watch my const-correctness and catch errors.

M
 
V

Vijai Kalyan

Yes, I did want to transfer the constness of the smart pointer to the
pointee. The reason is because I felt that since

SmartPointer <=> T const*

then maybe

const SmartPointer <=> T const* const

which seems consistent to me, although as you have pointed out copying
can workaround rid of this.

-vijai.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top