Re: Slightly OT: Compilation question
On Jun 17, 2:14 am, Paul Hsieh <websn...@gmail.com> wrote:
On Jun 16, 3:16 pm, "Alf P. Steinbach" <al...@start.no> wrote:
* 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. :-)
Its also enforced and the timing has to be at or *before* the
time of first instantiation, unless you do run-time deference
tricks (which have a performance and design impact.)
I'm not sure I understand what you are saying. In C++, if a
class needs a constructor, the implementor of the class provides
it, and it will be called. And the code wouldn't work correctly
if it wasn't. If the class doesn't need a constructor, the
author of the class doesn't provide it, and there's basically no
difference with respect to C.
Furthermore, its
easy to show that STL's vector templates have either ridiculously ba=
d
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().
Actual measurements on real implementations don't bear that out.
For dynamically sized arrays, std::vector is typically
considerably faster than anything you can do with
malloc/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.
Even for a mutatible vector? I am pretty sure MSVC and WATCOM
C/C++ both have problems with this and for good reason. You
definitely do not want to implement a vector as a linked list.
VC++ certainly doesn't. I often have vectors of objects without
default constructors, and in code which compiles with Sun CC,
g++ and VC++. (This has worked at least since VC++ 6.0, since
g++ 2.95.2, and since Sun CC 5.1. And those are all very old
compilers. In fact, I've never seen an implementation of the
STL where it didn't work.)
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.
That's why I called it a work around.
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,
I'm not sure I understand the objection here, either. Mail
messages are going to have variable lengths, so you can't put
them directly (as an image of the message) into a vector or a C
style array. In C, you'd probably have to use something like
char*[], with careful memory management when copying, etc. In
C++, the simplest solution would be to use
std::vector< MailMessage >, with MailMessage basically a wrapper
around std::string to start with; if the copying does end up
being too expensive, then you can easily fix it.
=46rom actual experience: if there's any risk of performance being
an issue, you must encapsulate. The result is that if there's
any risk of performance being an issue, C++ is essential.
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.
Uhh ... I was just hoping that C++'s std::vector did some
"magic" that made it as fast as I can do with late
initialization and realloc() without requiring I essentially
perform work equal or worse than doing it the C way in the
first place.
It does. In fact, because it has been optimized by some real
experts, it typically does a lot better than you or I could do.
It turns out, of course, that MSVC and WATCOM C/C++ do no
such thing. When it does a resize it allocates new space, and
simultaneously instantiating extra entries to mitigate
constant resizing thrashing, then copies the old contents into
the early part of its buffer. The first part of this appears
to instantiate the default constructor for your objects before
it does the eventual copy that you want performed.
What makes you think that? It most certainly doesn't. (At
least VC++ doesn't, nor does any C++ implementation that I've
ever seen.)
--
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