Re: Is it valid to initialize a base class with placement new?
On Sep 4, 3:44 pm, Juha Nieminen <nos...@thanks.invalid> wrote:
James Kanze wrote:
On Sep 4, 12:23 am, Juha Nieminen <nos...@thanks.invalid> wrote:
peter koch wrote:
Derived* ptr = allocator.allocate(1);
new (static_cast<Base*>(ptr)) Base(baseParameters);
new (&ptr->member) AnotherClass(otherParameters);
This compiles (and doesn't crash), but is it valid?
No. Not if member belongs to Derived.
How exactly are those lines I wrote above different from:
Derived* ptr = new Derived;
It calls the constructor of Derived.
(assuming, of course, that the constructor of Derived passes
the 'baseParameters' to Base and the 'otherParameters' to
'member', and that 'allocator' is the default allocator.)
In other words, does the 'new' do something that those three
lines I quoted above don't?
It calls the construtor of Derived. It does NOT call the
constructor of Base, nor does it call the constructor of
member; these are called by the constructor of Derived.
(The constructor of Derived may, and often does, other
things as well.)
I still fail to see how the end result is different from what
I wrote.
Try it. Formally, it's undefined behavior, so the results may
vary. But suppose Base is a polymorphic class (otherwise, why
inherit). And suppose that you then assign your pointer to a
Base*, and use typeid on it. What do you get?
'Derived' has no explicit constructor, and thus only the
compiler-generated one.
And? The compiler generated one may still have something it
needs to do.
Also, 'Derived' has no member functions, and the object of
type 'Derived' is never used for anything else than to access
the base class function and the function of 'Member'. The
destructor of 'Derived' is never called either (because I
never call it explicitly nor implicitly).
So basically the situation is that I have allocated space for
an object of type 'Base', with space for an object of type
'AnotherClass' appended to it, and then I construct that
'Base' object with placement new, as well as the 'member'
object. The 'Derived' struct is only a placeholder for this
allocated memory, and never used for anything else.
In which case, there shouldn't be any problem, if they're only
place holders, and you never use the object as a Derived. But I
don't see any case where I'd want to do that; if I just wanted
to group objects, I'd use a struct.
So what is it that makes it illegal to do so?
The standard. And the way most compilers implement inheritence.
(Why not simply have an object of type Base and another of
type AnotherClass and construct them normally? Because if Base
is an empty class, the compiler cannot perform empty base
optimization.)
Which it might not do anyway?
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34