Re: Slightly OT: Compilation question
[thread cross-posted to comp.lang.c++ and comp.lang.c]
* Paul Hsieh
On Jun 16, 12:10 pm, Ian Collins <ian-n...@hotmail.com> wrote:
Paul Hsieh wrote:
Using new and delete invoke
constructors which you might not want to happen.
No, as class designer you have full control over that. Or from a class user
perpective, if the class in question has at least one user defined constructor,
you usually really want some constructor invoked, so that you have some
invariants established. What C++ does here is to automate and check what you'd
do manually in C, and automation is great. :-)
Furthermore, its
easy to show that STL's vector templates have either ridiculously bad
performance in comparison to hand managed realloc()'s precisely
because of the RAII overhead or else compromise your design to the
point that you might as well use realloc().
Care to demonstrate?
Sure. Lets make a class of mail messages. Note that its impossible
to have an empty mail message (because there is always at least a
header), hence a mail message can only be initialized based on some
input text stream or string; there is no well defined concept of a
default mail message constructor. Further it makes very little sense
to mutate a mail message by changing its contents after the fact. So
its a well motivated read-only class without an empty or default
constructor.
Sure.
Now lets say you want to have a dynamic vector of mail messages (this
is exactly what you would expect a deserialized mailbox essentially to
be). The implementation of STL vectors require that the class have a
default constructor if the vector is modified (which it would be as a
result of incrementally reading the mailbox).
Direct use of a vector would probably be inappropriate, but accepting that for
the sake of argument.
Then, sorry, the information you have is incorrect: std::vector has no
requirement of a default constructor for the element type.
The C++98 requirement of a standard container element class is that it is
assignable[1] and copy constructible.
There are numerous work arounds to this such as creating a wrapper
class which does have an empty constructor which hides a pointer to a
mail message class that starts out NULL.
Hm, now you're talking about a vector of pointers. That imposes no requirements
on the class pointed to. Pointers are already assignable and copy constructible.
But individual new()s to
each one is still going to take extra overhead (performance + memory)
so you would prefer to point into a memory pool of your own which you
maintain with malloc() or realloc() anyways,
It seems you're now talking about a free list or more general custom allocator,
and mixing the requirements of the memory allocator abstraction level with the
requirements of the C++ class type object abstraction level.
That confusion is unfortunately easy to be led into when programming in either C
or C++, because C does not (let you) properly restrict you, and C++ accepts
almost all of C as a subset, modulo some teeny tiny small differences.
So when one's first instinct is to Do It Myself then the toolset the language
presents to you overwhelmingly consists of the Wrong Tools, such as exploiting
class level information at the allocator level. Choosing the Right Tools from
that multitude of apparently plausible tools, is difficult, especially, I think,
when one has been misinformed. At the allocator level you should only be dealing
with untyped raw chunks of memory.
With proper use of C++ you do the custom allocation stuff by defining, for the
class, a custom allocation function (unfortunately called 'operator new') and a
ditto custom deallocation function, which deal with untyped raw storage.
Or you might, better, inherit from a class that does that, which means you can
use a general already existing solution, such as e.g. the Loki small-object
allocator -- one little base class specification, and all that stuff's taken
care of. ;-)
in which case you have
not saved or improved anything by using these C++ constructs.
Right, if you mix too far apart abstraction levels then you get little or no
advantage from the abstraction.
And you can't fault a car for its tendency to run off the road or into walls
when you, as opposed to others, drive it. :-)
Sorry, couldn't resist that nag. :-)
Cheers, & hth.,
- Alf
Notes:
[1] The assignable requirement is silly and will be dropped for e.g. std::list
in C++0x.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?