Preventing delete on a SmartPointer

M

mathieu

Hi,

I have implemented a SmartPointer class following the implementation
proposed by Bill Hubauer(*). But I also override the operator * ()

template<class ObjectType>
class SmartPointer
{
public:
operator ObjectType * () const
{ return Pointer; }
....
private:
ObjectType* Pointer;
};

Now my compiler can compile:

SmartPointer<Object> s = new Object;
delete s;

Is there a way to prevent that ?

Thanks,
Mathieu

(*)
http://groups.google.com/group/comp.lang.c++/msg/173ddc38a827a930

Full source code is at:
http://svn.sourceforge.net/viewcvs.cgi/gdcm/Source/Common/gdcmSmartPointer.h?view=log
 
D

Daniel T.

"mathieu said:
Hi,

I have implemented a SmartPointer class following the implementation
proposed by Bill Hubauer(*). But I also override the operator * ()

template<class ObjectType>
class SmartPointer
{
public:
operator ObjectType * () const
{ return Pointer; }
...
private:
ObjectType* Pointer;
};

Now my compiler can compile:

SmartPointer<Object> s = new Object;
delete s;

Is there a way to prevent that ?

Yes. If you don't explicitly tell the compiler that this is allowed, it
won't allow it. That means remove the operator ObjectType*().
 
P

Phlip

Daniel said:
Yes. If you don't explicitly tell the compiler that this is allowed, it
won't allow it. That means remove the operator ObjectType*().

Of course that fix is the best style. (It's why the C++ Standard Library has
few if no conversion operators.)

But can't the templated class also provide an operator delete? Then it could
correctly zilch its owning pointer.
 
M

mathieu

Daniel said:
Yes. If you don't explicitly tell the compiler that this is allowed, it
won't allow it. That means remove the operator ObjectType*().

Well there is -at least- another way like defining the ~Object in the
protected section, but doing so would prevent me to define an Object on
the stack.
I thought there could be another way...

-M
 
A

Alf P. Steinbach

* Phlip:
Of course that fix is the best style. (It's why the C++ Standard Library has
few if no conversion operators.)

But can't the templated class also provide an operator delete? Then it could
correctly zilch its owning pointer.

An 'operator delete' in SmartPointer would be used in an expression like

delete &s;

not in

delete s;
 
R

Roland Pibinger

Well there is -at least- another way like defining the ~Object in the
protected section, but doing so would prevent me to define an Object on
the stack. I thought there could be another way...

It's yet another "smart" pointers pitfall. Just don't use "smart"
pointers and the 'problems' are gone.

Best wishes,
Roland Pibinger
 
B

benben

mathieu said:
Well there is -at least- another way like defining the ~Object in the
protected section, but doing so would prevent me to define an Object on
the stack.
I thought there could be another way...

-M

Unfortunately you can't make your smart pointer completely fool-proof.
At the very least one can still do the following:

SmartPointer<int> sp(new int(1));
delete sp.operator->();

Ben
 
M

Markus Schoder

benben said:
Unfortunately you can't make your smart pointer completely fool-proof.
At the very least one can still do the following:

SmartPointer<int> sp(new int(1));
delete sp.operator->();

Yes, and will all know how easily that accidentally happens :)

To shoot yourself in the foot with less typing do

delete &*sp;
 
M

Michiel.Salters

mathieu said:
Hi,

I have implemented a SmartPointer class following the implementation
proposed by Bill Hubauer(*). But I also override the operator * ()

template<class ObjectType>
class SmartPointer
{
public:
operator ObjectType * () const
{ return Pointer; }
...
private:
ObjectType* Pointer;
};

Now my compiler can compile:

SmartPointer<Object> s = new Object;
delete s;

Is there a way to prevent that ?

IIRC, the reason it can delete that is because there is exactly one
operator that
returns a pointer-to-object. If you had a private operator void*, the
compiler couldn't
determine which pointer type to cast to. This is good; the only case in
which you
want operator ObjectType* to work is the case where you need an
ObjectType*.
If the conversion context is ambiguous, like 'delete s', the compiler
should tell
you about the ambiguity.

HTH,
Michiel Salters
 
J

Joe Seigh

mathieu said:
Hi,

I have implemented a SmartPointer class following the implementation
proposed by Bill Hubauer(*). But I also override the operator * ()

template<class ObjectType>
class SmartPointer ....

Now my compiler can compile:

SmartPointer<Object> s = new Object;
delete s;

Is there a way to prevent that ?

I may have missed something here. If you haven't overridden
delete then it won't do anything since s is just an object,
not a pointer to a dynamically allocated object, as far as
C++ is concerned. The object your smart pointer "refers" to
won't get deallocated unless your smart pointer implementation
decides to do so.
 
M

mlimber

Roland said:
It's yet another "smart" pointers pitfall. Just don't use "smart"
pointers and the 'problems' are gone.

Better yet, go back to assembly, and then all the manifold problems
with high level languages disappear!

JK

Cheers! --M
 
P

Peter

mathieu said:
template<class ObjectType>
class SmartPointer
{
public:
operator ObjectType * () const
{ return Pointer; }
...
private:
ObjectType* Pointer;
};

Now my compiler can compile:

SmartPointer<Object> s = new Object;
delete s;

1)
your object class should have only private constructors and one or more
public static methods returning a smartPtr.
2)
Or instead of the static method you could define a factory class which
creates instances of your class (by returning a smartptr).
3)
You could make the destructor of Object private so nobody can call
delete on your object pointer.
I assume that your smartPtr is calling Addref() and Release() or
something similar on your object to increase/decrease the reference
count of your object.
 
P

Peter

mathieu said:
Well there is -at least- another way like defining the ~Object in the
protected section, but doing so would prevent me to define an Object on
the stack.
I thought there could be another way...

-M


But your are allowed to create an instance of smartPtr<Object> on the
stack.
I think your object should have only one lifetime philosophy --
reference counted with smart pointers or not.
 
P

Peter

mathieu said:
Well there is -at least- another way like defining the ~Object in the
protected section, but doing so would prevent me to define an Object on
the stack.
I thought there could be another way...

-M


But your are allowed to create an instance of smartPtr<Object> on the
stack.
I think your object should have only one lifetime philosophy --
reference counted with smart pointers or not.
 

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,776
Messages
2,569,602
Members
45,185
Latest member
GluceaReviews

Latest Threads

Top