Re: vtbl inheritance
On Jan 31, 7:51 am, Goran <goran.pu...@gmail.com> wrote:
On Jan 30, 5:14 pm, "Serve Laurijssen" <spamj...@stnyy.rrr.com> wrote:
Consider this code:
class RefCounted {
private: long m_nRefCount;
public: virtual ~RefCounted();
};
struct Header {
short us;
int i1;
int i2;
};
struct UnitHeader: public Header {
BYTE filler[sizeof(ULONG) - (sizeof(UnitHeader) & (sizeof(ULONG) - 1))];
};
class CHeader : public UnitHeader, public RefCounted {
};
RefCounted has a virtual destructor, UnitHeader and Header are POD structs.
CHeader inherits from UnitHeader and RefCounted.
Now consider this:
void CHeader::MakeDummy() {
memset((UnitHeader*)this, 0, sizeof(UnitHeader));}
The 'this' pointer in CHeader is casted to UnitHeader struct
and that memory area set to zero. But since the class
inherits from a class with a virtual destructor Im not sure
this works.
I, too, think this should work.
It's certainly not guaranteed.
How does MSVC(2005) handle the Vtbl when inheriting from a
class with a vtbl?
Don't know about 2005 specifically, but 98, 2003 and 2008 do this:
class WithoutVtbl
m1
m2
...
mx
class WithVtbl
vtbl
m1
m2
...
mx
class WithoutWithVtbl : public WithoutVtbl, public WithVtbl
WithoutVtbl::m1
...
WithVtbl::vtbl
WithVtbl::m1
...
Where does it put the second vptr?
In fact, that's not what VC++ 2005 nor g++ do. Interestingly
enough, they both systematically place base classes without
virtual functions *after* those with, in order to be able to get
by with only one vptr. (This has a second effect as well: the
memset trick will never cause a problem if the class which is
doing it happens to be the last one in the order the compiler
lays them out.
[...]
That said... What you actually seem to want is a POD (Header), then a
derived POD from it (UnitHeader), then your actual object, and you
want 0-initialization of PODs. If so, you might want to try this
(discalimer: compiled with head-compiler 0.0.1 and tested with head-
test-suite 0.0.1):
UnitHeader zeroFilled();
In CHeader, you might have
CHeader::CHeader()
{
static_cast<UnitHeader&>(*this) = UnitHeader();
}
Just:
CHeader::CHeader()
: UnitHeader()
{
}
should do the trick.
--
James Kanze