|
|
|
|
|
|
|
|
|
|
|
|
ISO C++
|
ISO C++
|
|
|
|
|
auto_ptr
|
auto_ptr
|
|
|
|
|
|
|
|
|
auto_ptr
|
auto_ptr
|
|
|
|
|
Limitations
|
Limitations
|
|
|
Explaining all of the fun and delicious things that can
|
Explaining all of the fun and delicious things that can
|
happen with misuse of the auto_ptr class
|
happen with misuse of the auto_ptr class
|
template (called AP here) would take some
|
template (called AP here) would take some
|
time. Suffice it to say that the use of AP
|
time. Suffice it to say that the use of AP
|
safely in the presence of copying has some subtleties.
|
safely in the presence of copying has some subtleties.
|
|
|
|
|
The AP class is a really
|
The AP class is a really
|
nifty idea for a smart pointer, but it is one of the dumbest of
|
nifty idea for a smart pointer, but it is one of the dumbest of
|
all the smart pointers -- and that's fine.
|
all the smart pointers -- and that's fine.
|
|
|
|
|
AP is not meant to be a supersmart solution to all resource
|
AP is not meant to be a supersmart solution to all resource
|
leaks everywhere. Neither is it meant to be an effective form
|
leaks everywhere. Neither is it meant to be an effective form
|
of garbage collection (although it can help, a little bit).
|
of garbage collection (although it can help, a little bit).
|
And it can notbe used for arrays!
|
And it can notbe used for arrays!
|
|
|
|
|
AP is meant to prevent nasty leaks in the
|
AP is meant to prevent nasty leaks in the
|
presence of exceptions. That's all. This
|
presence of exceptions. That's all. This
|
code is AP-friendly:
|
code is AP-friendly:
|
|
|
|
|
// Not a recommend naming scheme, but good for web-based FAQs.
|
// Not a recommend naming scheme, but good for web-based FAQs.
|
typedef std::auto_ptr<MyClass> APMC;
|
typedef std::auto_ptr<MyClass> APMC;
|
|
|
extern function_taking_MyClass_pointer (MyClass*);
|
extern function_taking_MyClass_pointer (MyClass*);
|
extern some_throwable_function ();
|
extern some_throwable_function ();
|
|
|
void func (int data)
|
void func (int data)
|
{
|
{
|
APMC ap (new MyClass(data));
|
APMC ap (new MyClass(data));
|
|
|
some_throwable_function(); // this will throw an exception
|
some_throwable_function(); // this will throw an exception
|
|
|
function_taking_MyClass_pointer (ap.get());
|
function_taking_MyClass_pointer (ap.get());
|
}
|
}
|
|
|
When an exception gets thrown, the instance of MyClass that's
|
When an exception gets thrown, the instance of MyClass that's
|
been created on the heap will be delete'd as the stack is
|
been created on the heap will be delete'd as the stack is
|
unwound past func().
|
unwound past func().
|
|
|
Changing that code as follows is not AP-friendly:
|
Changing that code as follows is not AP-friendly:
|
|
|
|
|
APMC ap (new MyClass[22]);
|
APMC ap (new MyClass[22]);
|
|
|
You will get the same problems as you would without the use
|
You will get the same problems as you would without the use
|
of AP:
|
of AP:
|
|
|
|
|
char* array = new char[10]; // array new...
|
char* array = new char[10]; // array new...
|
...
|
...
|
delete array; // ...but single-object delete
|
delete array; // ...but single-object delete
|
|
|
|
|
AP cannot tell whether the pointer you've passed at creation points
|
AP cannot tell whether the pointer you've passed at creation points
|
to one or many things. If it points to many things, you are about
|
to one or many things. If it points to many things, you are about
|
to die. AP is trivial to write, however, so you could write your
|
to die. AP is trivial to write, however, so you could write your
|
own auto_array_ptr for that situation (in fact, this has
|
own auto_array_ptr for that situation (in fact, this has
|
been done many times; check the mailing lists, Usenet, Boost, etc).
|
been done many times; check the mailing lists, Usenet, Boost, etc).
|
|
|
|
|
|
|
|
|
Use in Containers
|
Use in Containers
|
|
|
|
|
|
|
All of the containers
|
All of the containers
|
described in the standard library require their contained types
|
described in the standard library require their contained types
|
to have, among other things, a copy constructor like this:
|
to have, among other things, a copy constructor like this:
|
|
|
|
|
struct My_Type
|
struct My_Type
|
{
|
{
|
My_Type (My_Type const&);
|
My_Type (My_Type const&);
|
};
|
};
|
|
|
|
|
Note the const keyword; the object being copied shouldn't change.
|
Note the const keyword; the object being copied shouldn't change.
|
The template class auto_ptr (called AP here) does not
|
The template class auto_ptr (called AP here) does not
|
meet this requirement. Creating a new AP by copying an existing
|
meet this requirement. Creating a new AP by copying an existing
|
one transfers ownership of the pointed-to object, which means that
|
one transfers ownership of the pointed-to object, which means that
|
the AP being copied must change, which in turn means that the
|
the AP being copied must change, which in turn means that the
|
copy ctors of AP do not take const objects.
|
copy ctors of AP do not take const objects.
|
|
|
|
|
The resulting rule is simple: Never ever use a
|
The resulting rule is simple: Never ever use a
|
container of auto_ptr objects. The standard says that
|
container of auto_ptr objects. The standard says that
|
undefined behavior is the result, but it is
|
undefined behavior is the result, but it is
|
guaranteed to be messy.
|
guaranteed to be messy.
|
|
|
|
|
To prevent you from doing this to yourself, the
|
To prevent you from doing this to yourself, the
|
concept checks built
|
concept checks built
|
in to this implementation will issue an error if you try to
|
in to this implementation will issue an error if you try to
|
compile code like this:
|
compile code like this:
|
|
|
|
|
#include <vector>
|
#include <vector>
|
#include <memory>
|
#include <memory>
|
|
|
void f()
|
void f()
|
{
|
{
|
std::vector< std::auto_ptr<int> > vec_ap_int;
|
std::vector< std::auto_ptr<int> > vec_ap_int;
|
}
|
}
|
|
|
|
|
Should you try this with the checks enabled, you will see an error.
|
Should you try this with the checks enabled, you will see an error.
|
|
|
|
|
|
|
|
|
|
|