AutoPointer template

S

Stefan Arentz

To understand auto_ptr I mocked up this replacement class. This is also
basically my first usage of templates.

template<class X> class AutoPointer {

public:

AutoPointer(X* clazz)
: mClass(clazz)
{
}

~AutoPointer()
{
delete mClass;
}

X& operator*() const
{
return *mClass;
}

X* operator->() const
{
return mClass;
}

private:

X* mClass;

};

Now, I have this:

class Foo {

public:

Foo()
{
::printf("Foo constructor\n");
}

~Foo()
{
::printf("Foo destructor\n");
}

};

int main()
{
AutoPointer<Foo> foo = new Foo;
AutoPointer<char> bar = new char[10];
}

And that outputs the expected. Great. Heap objects that are automatically
destroyed when they go out of scope. Didn't know it would be that easy.

But, in the 'the finally debate' thread somebody gave this auto_ptr example:

std::auto_ptr<char> my_ptr(new char[987]);

Which translates to this with my template:

AutoPointer<char> bar = new char[10];

It compiles fine, which I find odd, since the template definition states:

template<class X> class AutoPointer {
^^^^^

that X should be a class right? So why does it accept a char* in this case? Is there
any way to prevent that?

S.
 
V

Victor Bazarov

Stefan said:
To understand auto_ptr I mocked up this replacement class. This is also
basically my first usage of templates.

template<class X> class AutoPointer {

public:

AutoPointer(X* clazz)
: mClass(clazz)
{
}

~AutoPointer()
{
delete mClass;
}

X& operator*() const
{
return *mClass;
}

X* operator->() const
{
return mClass;
}

private:

X* mClass;

};

Now, I have this:

class Foo {

public:

Foo()
{
::printf("Foo constructor\n");
}

~Foo()
{
::printf("Foo destructor\n");
}

};

int main()
{
AutoPointer<Foo> foo = new Foo;
AutoPointer<char> bar = new char[10];
}

And that outputs the expected. Great. Heap objects that are automatically
destroyed when they go out of scope. Didn't know it would be that easy.

Actually, you're invoking undefined behaviour. The 'bar' object frees
its 'mClass' variable using 'delete' while the pointer it got was obtained
using 'new[]'. That's a big mistake.
But, in the 'the finally debate' thread somebody gave this auto_ptr example:

std::auto_ptr<char> my_ptr(new char[987]);

Which translates to this with my template:

AutoPointer<char> bar = new char[10];

It compiles fine, which I find odd, since the template definition states:

template<class X> class AutoPointer {
^^^^^

that X should be a class right?

No, it can be of any type for which certain requested operations are
provided (like declaring a pointer of).
So why does it accept a char* in this case? Is there
any way to prevent that?

No, there is no way to prevent that.

I don't mean to rain on your parade, but your AutoPointer class is
also defective in a different way: it does not have proper copying set up
(copy c-tor and the assignment op).

Victor
 
S

Stefan Arentz

....
Actually, you're invoking undefined behaviour. The 'bar' object frees
its 'mClass' variable using 'delete' while the pointer it got was obtained
using 'new[]'. That's a big mistake.

Well that is why I ask the real question a little bit below in this posting.
But, in the 'the finally debate' thread somebody gave this auto_ptr
example:
std::auto_ptr<char> my_ptr(new char[987]);
Which translates to this with my template:
AutoPointer<char> bar = new char[10];
It compiles fine, which I find odd, since the template definition
states:
template<class X> class AutoPointer {
^^^^^
that X should be a class right?

No, it can be of any type for which certain requested operations are
provided (like declaring a pointer of).
So why does it accept a char* in this case? Is there
any way to prevent that?

No, there is no way to prevent that.

Bah I hope you are wrong. Or else this is another great way to shoot++ yourself
in the foot :)

S.
 
V

Victor Bazarov

Stefan said:
But, in the 'the finally debate' thread somebody gave this auto_ptr
example:
std::auto_ptr<char> my_ptr(new char[987]);
Which translates to this with my template:
AutoPointer<char> bar = new char[10];
It compiles fine, which I find odd, since the template definition
states:
template<class X> class AutoPointer {
^^^^^
that X should be a class right?

No, it can be of any type for which certain requested operations are
provided (like declaring a pointer of).
So why does it accept a char* in this case? Is there
any way to prevent that?

No, there is no way to prevent that.


Bah I hope you are wrong. Or else this is another great way to shoot++ yourself
in the foot :)

A pointer is just a pointer whether it points to a single object or to
an array of them. There is no platform-independent way to figure out
the difference. The language states that anything allocated using
'new[]' has to be disposed of using 'delete[]' and, symmetrically,
anything allocated using 'new' needs 'delete' to be freed. That is
to some extend a limitation of the language, and I've heard scores of
people complaining about it. But it's not going to change any time
soon. Or maybe it will. Ask in comp.std.c++, they talk about the
Standard document and its upcoming changes.

As to prohibiting your AutoPointer from being used with 'char', that's
relatively easy: define a specialisation of AutoPointer, and define all
its members private. There would be no way to instantiate it.

Victor
 
J

Jonathan Turkanis

Stefan Arentz said:
To understand auto_ptr I mocked up this replacement class. This is also
basically my first usage of templates.

Bad choice for your first use of templates. std::auto_ptr may actually be
impossible to implement correctly as currently specified. (See some of the
references cited in the link below.)
int main()
{
AutoPointer<Foo> foo = new Foo;
AutoPointer<char> bar = new char[10];
}

If you want arrays to be treated correcty, try this implementation of move_ptr:

http://home.comcast.net/~jturkanis/move_ptr/

(Disclaimer: it's not currently part of Boost)

Usage is as follows:

int main()
{
boost::static_move_ptr<Foo> foo(new Foo);
boost::static_move_ptr<char[]> bar(new char[10]);
}

(This syntax was suggested by Howard Hinnant.)

Best Regards,
Jonathan
 

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,780
Messages
2,569,611
Members
45,271
Latest member
BuyAtenaLabsCBD

Latest Threads

Top