Topic: auto_ptr: Why get() function instead of pointer cast operator?


Author: "John Hickin" <hickin@nortel.ca>
Date: 1998/07/09
Raw View
It prevents accidents. Try the following code below, has both operator T*() and
T* operator->():

template<class T>
struct X {
  T* data;
  X() : data( new T ) {}
  operator T*()    { return data; }
  //operator void*() { return this; }
  T* operator->()  { return data; }
};

#include <iostream.h>

struct Y
{
  ~Y() { cout << "..toast!\n"; }
};

int main()
{
  X<Y> anX;
  delete anX;
}

If you add the operator void*(), however, you could have oeratorT*().
--
John D. Hickin      Nortel Technology, Montreal, Quebec
(514) 765-7924   hickin@nortel.ca
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Colin Rafferty <craffert@ms.com>
Date: 1998/07/09
Raw View
John Hickin writes:

> It prevents accidents. Try the following code below, has both operator T*() and
> T* operator->():

> template<class T>
> struct X {
>   T* data;
>   X() : data( new T ) {}
>   operator T*()    { return data; }
>   //operator void*() { return this; }
>   T* operator->()  { return data; }
> };

> #include <iostream.h>

> struct Y
> {
>   ~Y() { cout << "..toast!\n"; }
> };

> int main()
> {
>   X<Y> anX;
>   delete anX;
> }

> If you add the operator void*(), however, you could have oeratorT*().

Even then, you couldn't have operator T*().  Imagine your sample code,
but with X::operator void*() uncommented:

    void f(Y* y)
    {
      delete y;
    }

    void g()
    {
      X<Y> anX;
      f(y);      // not ambiguous, but definitely bad.
    }

The implicit cast is thoroughly unambiguous, and we still have the
same problem, just a little harder to notice.

--
Colin
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Jorn Ronnow" <d97jorn.remove_this@dtek.thisgoesaway.chalmers.se>
Date: 1998/07/09
Raw View
John Hickin wrote in message <6o2jcm$dmt@bmtlh10.bnr.ca>...

>It prevents accidents.

[snip]

>int main()
>{
>  X<Y> anX;
>  delete anX;
>}
>
>If you add the operator void*(), however, you could have oeratorT*().


Is this really the only reason? C++ is generally free from safeguards, e.g.
the following is compilable:

void main()
{
  int x;

  // the programmer shoots himself in the foot, legally:
  delete &x;
}

I thought there might be a situation where the compiler would be confused
(for example when resolving overloading?), but I can't think of any such
situation.

Anyway, using a private operator void*() is a good idea!

cul8r/Jorn



[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "John Hickin" <hickin@nortel.ca>
Date: 1998/07/11
Raw View
> Anyway, using a private operator void*() is a good idea!

For those forwarned it may provide a little extra protection but (see Colin
Rafferty's reply) it isn't foolproof.

In general, implicit cast operators which return a pointer or reference to
private data can often lead to undesireable results. I believe that's why
basic_string has no implicit cast.

--
John D. Hickin      Nortel Technology, Montreal, Quebec
(514) 765-7924   hickin@nortel.ca
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1998/07/11
Raw View
"Jorn Ronnow" <d97jorn.remove_this@dtek.thisgoesaway.chalmers.se> writes:

>Is this really the only reason? C++ is generally free from safeguards, e.g.
>the following is compilable:

>void main()
>{
>  int x;

>  // the programmer shoots himself in the foot, legally:
>  delete &x;
>}

Let's not confuse what some compilers do with what the language
defintion says.

The draft standard says that deleting a pointer for which there
is no matching new is not valid; the results are undefined.

Some compilers might let this code go by (which they are
allowed to do). A compiler might diagnose the error at compile
time, but it is unlikely.  Many current implementations provide the
option of catching the error at run time.


--
Steve Clamage, stephen.clamage@sun.com
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Bill Wade" <bill.wade@stoner.com>
Date: 1998/07/11
Raw View
Jorn Ronnow wrote in message <6o36mq$mr7$1@oden.abc.se>...
>Is this really the only reason?

One good use for auto_ptr is a return result from functions that allocate
memory:



auto_ptr<T> GiveMeAT();
L1: T* tp = GiveMeAT();
L2: tp->DoSomething();    // Undefined

L1 is not legal, but would be if operator T*() existed.  Note that the
allocated memory is deleted before L2 is executed. (after the assignment the
temporary auto_ptr is destructed).

Since the compiler doesn't allow L1 as-is I must change it to one of

  auto_ptr<T> tp = GiveMeAT();     // Now L2 works.
or
  T* tp = GiveMeAT().get();        // I'm an idiot
or
  T* tp = GiveMeAT().release();    // Some chance of being correct.

Since the original L1 doesn't have the semantics you might expect, IMO it is
a good thing that the compiler tells me to take a closer look.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/07/12
Raw View
Bill Wade<bill.wade@stoner.com> wrote:
>One good use for auto_ptr is a return result from functions that allocate
>temporary auto_ptr is destructed).
>...
>  auto_ptr<T> tp = GiveMeAT();     // Now L2 works.
>or
>  T* tp = GiveMeAT().get();        // I'm an idiot
>or
>  T* tp = GiveMeAT().release();    // Some chance of being correct.

I had advocated calling the function "leak" rather than "get",
but the working group was too weenie to go for that.  :-)

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.org/
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Jorn Ronnow" <d97jorn.remove_this@dtek.thisgoesaway.chalmers.se>
Date: 1998/07/09
Raw View
Below is an enhanced (?) auto_ptr, where a pointer cast operator "operator
T* ()" is added so that you don't need to call auto_ptr::get() explicitly.

Since auto_ptr is standardized, I suspect there is a good reason for not
having an "operator T* ()" in the class. What reason might that be???

cul8r
/J   rn

#include <memory>

template<class T> class auto_ptr2 : public std::auto_ptr<T>
{
  public:
    explicit auto_ptr2 (T* p=0) : std::auto_ptr<T>(p) {}
    auto_ptr2( auto_ptr2& a ) : std::auto_ptr<T>(a) {}
    operator T*() const { return get(); }
};
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]