Jim Starkey wrote:
Eric Day wrote:
Why? Isn't it a great deal clearer to put the initialization code in
the constructor? There certainly is any different in code size or
speed, so why not go for clarity?
Constructor initializer lists should be perfectly clear to any C++
programmer. If not, it's worth taking the time to make it so. It
shouldn't really be a matter of preference, it's just the correct
thing to do.
It's more clear because a) assignments should look like assignments,
b) not all initialization code fits in parameter initialization, and
c) code executed in a block should be in one place.
It's not just a matter of clarity, but also of performance and
correctness. For example:
class Foo
{
std::string& bar;
public:
Foo(const std::string& bar_arg):
bar(bar_arg)
{}
}
Is more efficient than:
class Foo
{
std::string& bar;
public:
Foo(const std::string& bar_arg)
{
bar= bar_arg;
}
}
In the second case, the default std::string constructor gets called,
than the copy operator is called. The first case only has the
constructor taking an argument. Remember a default constructor is
called for every member that has one before entering the body of the
constructor, and you want to avoid those double assignments.
In an ordinary method, assignments to class variables "int foo" and
"std::string bar" look like this:
foo = 123;
bar = aString;
But you are arguing in the special case of constructors, these should be
written as:
foo(123), bar(aString)
To my eye -- and grep's -- "foo(123)" looks like a function invocation,
It *is* a function invocation. It's the constructor invocation.
not an assignment. The project has agreed on a standard operator
spacing for assignments to aid searching. Why don't this apply to
initialization in constructors as well?
Because the project has agreed on a style for *assignment*, and
initializer lists are not assignment. They are initialization.
That said, I'm *not* generally in favor of putting constructor
definitions in header files at all. The reason is that when a
constructor's definition is in the header file, it is (attempted to be)
inlined by the compiler. When an object has quite a few data members,
particularly data members which are objects (such as std::string), the
default constructors of all of those member variables are, by default,
pulled into the inlined constructor, which needlessly bloats code for
almost no performance gain...
As for efficiency, the initialization form invokes a single
constructor. The assignment case does call the default constructor to
create the object then the copy constructor for the assignment. The
delta is negligible and utterly masked by almost any call to std:: (I
once counted 56 machine instructions to dereference an element in an
array template.)
See Meyers' Effective C++, 3rd Edition, Items 4 and 26.
As for your previous comment about wishing all C++ developers first
learned Java, sure, it's fine to have some experience with Java, but
unfortunately, learning Java *first*, many developers fail to understand
that OOP is *not* appropriate in many places in C++, and procedural and
generic/meta programming are more appropriate. Also, Java developers
simply never learn the intricacies of memory management and resource
ownership issues that experienced C++ developers have a grab-bag of
techniques to use to solve different problems. Put briefly: to Java
developers, everything looks like a nail since all they have is (an
object-oriented) hammer.
-jay
_______________________________________________
Mailing list: https://launchpad.net/~drizzle-discuss
Post to : [email protected]
Unsubscribe : https://launchpad.net/~drizzle-discuss
More help : https://help.launchpad.net/ListHelp