Re: A Sample auto_ptr implementation
On Oct 13, 10:10 pm, Ankur Arora <ankuraror...@gmail.com> wrote:
Thanks for the reply Kai!
Please see the comments below.
On Oct 13, 2:53 pm, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
Ankur Arora wrote:
Hi All,
I'm building a sample application that uses a custom auto_ptr
implementation.
The program crashes with the following output:-
Output (Debug Assertion failed)
----------
release called
copy constructor
aap: ptr2= 10
aap: ptr3= 20
aap: ptr3= 10
aap: exiting app
Deleting pointee...10
Deleting pointee...-572662307 (...=
problem ?)
Code
--------
Just a data point: your code works for me with output
release called
copy constructor
aap: ptr2= 10
aap: ptr3= 20
Inside operator=
Inside operator=, calling reset
release called
reset called
aap: ptr3= 10
aap: exiting app
Deleting pointee...10
So I just have nits:
#include<iostream>
using namespace std;
It's a bad idea to use using namespace std in a header.
Agreed!
[snip]
template <class T>
inline MyAutoPtr<T>::~MyAutoPtr()
{
if(pointee)
{
cout<<"\n\t Deleting pointee..."<<*pointee;
delete pointee;
}
}
delete will perform its own check for 0. It is required to be a null-op=
in
that case.
I did this since removing this check caused the program to crash, even
though I had made pointee equals to 0 in release(), which was used in
the copy constructor.
I'm using visual studio 2008 express edition. You reckon this is a
complier issue?
[snip]
template<class T>
template<class U>
MyAutoPtr<T>& MyAutoPtr<T>::operator=(MyAutoPtr<U>& rhs)
{
cout<<"\n\t Inside operator=";
if(this!=&rhs)
This if-clause will not compile when T and U are different.
You could use
if ( this->pointee == rhs.pointee )
instead (I think).
I saw this example in "More Effective C++" by scott meyers. This was
how its used in that book. Here is a code.
//Interface
template<class T>
class auto_ptr {
public:
explicit auto_ptr(T *p = 0); // see Item=
5 for a
=
// description of
"explicit"
template<class U> // =
copy constructor member
auto_ptr(auto_ptr<U>& rhs); // template (=
see Item 28):
=
// initialize a new
auto_ptr
=
// with any compatible
=
// auto_ptr
~auto_ptr();
template<class U> // =
assignment operator
auto_ptr<T>& =
// member template (see
operator=(auto_ptr<U>& rhs); // Item 28)=
: assign from
any
=
// compatible auto_ptr
T& operator*() const; // see =
Item 28
T* operator->() const; // see =
Item 28
T* get() const; /=
/ return value of current
=
// dumb pointer
T* release(); =
// relinquish ownership of
=
// current dumb pointer
and
=
// return its value
void reset(T *p = 0); // de=
lete owned pointer;
=
// assume ownership of p
private:
T *pointee;
template<class U> // =
make all auto_ptr
classes
friend class auto_ptr<U>; // friends =
of one another
};
//Implementation
template<class T>
inline auto_ptr<T>::auto_ptr(T *p)
: pointee(p)
{}
template<class T>
inline auto_ptr<T>::auto_ptr(auto_ptr<U>& rhs)
: pointee(rhs.release())
{}
template<class T>
inline auto_ptr<T>::~auto_ptr()
{ delete pointee; }
template<class T>
template<class U>
inline auto_ptr<T>& auto_ptr<T>::operator=(auto_ptr<U>& rhs)
{
if (this != &rhs) reset(rhs.release());
return *this;
}
template<class T>
inline T& auto_ptr<T>::operator*() const
{ return *pointee; }
template<class T>
inline T* auto_ptr<T>::operator->() const
{ return pointee; }
template<class T>
inline T* auto_ptr<T>::get() const
{ return pointee; }
template<class T>
inline T* auto_ptr<T>::release()
{
T *oldPointee = pointee;
pointee = 0;
return oldPointee;}
template<class T>
inline void auto_ptr<T>::reset(T *p)
{
if (pointee != p) {
delete pointee;
pointee = p;
}
}
Anything wrong with the above ? (would be surprised if there is, as it
came from scott meyers)
Q1. Any problems with the above code ?
There's a reversion for auto_ptr (IIRC, a article is proviede by Mayer
on
this), adding auto_ptr_ref for conversion, which supports rvalue
initialization for auto_ptr. which is done transparently.
void fun(auto_ptr<T> ptr);
fun(auto_ptr(new T)); // rvalue -> auto_ptr_ref -> auto_ptr
It works with g++.
Again, looks like an issue with visual studio 2008 express.
there are two problem with visual C++ 2005 in this issue:
1. as extension, "explicit" does NOT work as standard says.
needs /Za switch to turn it off.
2. auto_ptr_ref use void* rather T*
point 2 is fixed by VS 2008(none expression version,
but I expression version should ship the same lib)
Q2. What is causing operator= not to be called and how to fix it ?
A bug in your compiler?
[snip]
--
Best Regards
Barry