Re: Virtual calls upon destruction
Jeremy Jurksztowicz wrote:
[snip]
So what the hell have I done? I am assuming that bptr will point to a
fully constructed object, and thus the correct functions will be
called.
Nope; by the time operator delete is called, all destructors will be
executed and bptr will point to uninitialized memory.
Instead, you want something like this:
class Base
{
public:
virtual ~Base();
void deleteMe()
{
this->uninitialize();
delete this;
}
virtual void uninitialize() = 0;
};
class Derived : public Base
{
public:
virtual void uninitialize();
};
void F()
{
Derived* d(new Derived());
// ...
d->deleteMe();
}
This has the disadvantage that there's no way in general to stop
someone from deleting such a pointer directly and circumventing the
uninitialize() member function, but some improvements can be made
(e.g., making the Base destructor protected). You could also wrap this
into a tr1 shared_ptr that automatically does the right thing:
struct DeleteMe
{
void operator()(Base* p)
{
p->deleteMe();
}
};
// Note: Won't compile unless T* is convertible to Base*:
template<typename T>
std::tr1::shared_ptr<T> MakeDeleteMePtr(T* p)
{
return std::tr1::shared_ptr<T>(p, DeleteMe());
}
void F()
{
std::tr1::shared_ptr<Derived> p(MakeDeleteMePtr(new Derived()));
// ...
}
Bob
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]