 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
swengtoo Guest
|
Posted: Thu Dec 15, 2005 11:23 pm Post subject: private default constructor is good or bad? |
|
|
In his book "More Effective C++", Scott Meyer suggests in "Item 4" to
"Avoid gratuitous default constructors".
To summarize his claims against default constructors for "the right
classes" he states that:
================== START QUOTE =============
"A default constructor is the C++ way of saying you can get something
for nothing. Constructors initialize objects, so default constructors
initialize objects without any information from the place where the
object is being created. Sometimes this makes perfect sense. Objects
that act like numbers, for example, may reasonably be initialized to
zero or to undefined values. Objects that act like pointers may
reasonably be initialized to null or to undefined values. Data
structures like linked lists, hash tables, maps, and the like may
reasonably be initialized to empty containers.
Not all objects fall into this category. For many objects, there is no
reasonable way to perform a complete initialization in the absence of
outside information. For example, an object representing an entry in an
address book makes no sense unless the name of the thing being entered
is provided. In some companies, all equipment must be tagged with a
corporate ID number, and creating an object to model a piece of
equipment in such companies is nonsensical unless the appropriate ID
number is provided.
Inclusion of meaningless default constructors affects the efficiency of
classes, too. If member functions have to test to see if fields have
truly been initialized, clients of those functions have to pay for the
time those tests take. Furthermore, they have to pay for the code that
goes into those tests, because that makes executables and libraries
bigger. They also have to pay for the code that handles the cases where
the tests fail. All those costs are avoided if a class's constructors
ensure that all fields of an object are correctly initialized. Often
default constructors can't offer that kind of assurance, so it's best
to avoid them in classes where they make no sense. That places some
limits on how such classes can be used, yes, but it also guarantees
that when you do use such classes, you can expect that the objects they
generate are fully initialized and are efficiently implemented."
================== END QUOTE =============
Now... I tried to follow this guideline (among others), by declaring a
private default constructor for a class that seems to be useless
without being properly initialized with some values.
However, this created a problem of inability to optimize my application
for speed. The reason is that in my particular case I am re-creating a
database record (represented by the aforementioned class with private
ctor) on the heap in a pretty huge loop. The call to 'new' is very
costly in terms of CPU cycles... I realized I can improve performance
greatly if I instantiate this record only once *outside* the loop.
However, outside the loop I don't have any meaningful values to
initialize that record with, so a default constructor seems to be
required here...
So, my question is: how do I solve the dilemma? On one hand, from the
*logical correctness* point of view, it doesn't make sense for my class
to have a default constructor. On the other hand, from *performance*
point of view a default constructor is required (or using some dummy
values for the non-default ctor, which is basically the same).
Can performance considerations justify violation of "elegant
implementation"?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Gerhard Menzl Guest
|
Posted: Fri Dec 16, 2005 10:34 am Post subject: Re: private default constructor is good or bad? |
|
|
swengtoo wrote:
[Scott Meyers qoute snipped]
| Quote: | Now... I tried to follow this guideline (among others), by declaring a
private default constructor for a class that seems to be useless
without being properly initialized with some values.
However, this created a problem of inability to optimize my
application for speed. The reason is that in my particular case I am
re-creating a database record (represented by the aforementioned class
with private ctor) on the heap in a pretty huge loop. The call to
'new' is very costly in terms of CPU cycles... I realized I can
improve performance greatly if I instantiate this record only once
*outside* the loop. However, outside the loop I don't have any
meaningful values to initialize that record with, so a default
constructor seems to be required here...
So, my question is: how do I solve the dilemma? On one hand, from the
*logical correctness* point of view, it doesn't make sense for my
class to have a default constructor. On the other hand, from
*performance* point of view a default constructor is required (or
using some dummy values for the non-default ctor, which is basically
the same).
|
If you don't have any meaningful values outside the loop, what values
would you choose in the default constructor?
| Quote: | Can performance considerations justify violation of "elegant
implementation"?
|
In principle, yes, provding the violation is based on reliable
measurements. But I don't see what difference it would make in your
case. If you can write a default constructor, you can also instantiate
an object passing the values you would use to the non-default constructor.
--
Gerhard Menzl
#dogma int main ()
Humans may reply by replacing the thermal post part of my e-mail address
with "kapsch" and the top level domain part with "net".
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Greg Herlihy Guest
|
Posted: Fri Dec 16, 2005 10:38 am Post subject: Re: private default constructor is good or bad? |
|
|
swengtoo wrote:
| Quote: | In his book "More Effective C++", Scott Meyer suggests in "Item 4" to
"Avoid gratuitous default constructors".
To summarize his claims against default constructors for "the right
classes" he states that:
================== START QUOTE =============
"A default constructor is the C++ way of saying you can get something
for nothing. Constructors initialize objects, so default constructors
initialize objects without any information from the place where the
object is being created. Sometimes this makes perfect sense. Objects
that act like numbers, for example, may reasonably be initialized to
zero or to undefined values. Objects that act like pointers may
reasonably be initialized to null or to undefined values. Data
structures like linked lists, hash tables, maps, and the like may
reasonably be initialized to empty containers.
Not all objects fall into this category. For many objects, there is no
reasonable way to perform a complete initialization in the absence of
outside information. For example, an object representing an entry in an
address book makes no sense unless the name of the thing being entered
is provided. In some companies, all equipment must be tagged with a
corporate ID number, and creating an object to model a piece of
equipment in such companies is nonsensical unless the appropriate ID
number is provided.
....
================== END QUOTE =============
Now... I tried to follow this guideline (among others), by declaring a
private default constructor for a class that seems to be useless
without being properly initialized with some values.
However, this created a problem of inability to optimize my application
for speed. The reason is that in my particular case I am re-creating a
database record (represented by the aforementioned class with private
ctor) on the heap in a pretty huge loop. The call to 'new' is very
costly in terms of CPU cycles... I realized I can improve performance
greatly if I instantiate this record only once *outside* the loop.
However, outside the loop I don't have any meaningful values to
initialize that record with, so a default constructor seems to be
required here...
So, my question is: how do I solve the dilemma? On one hand, from the
*logical correctness* point of view, it doesn't make sense for my class
to have a default constructor.
From what I understand, there is a loop that instantiates a set of
database records. The choice for the implementation is whether to |
allocate a database record object once, outside the loop and then
re-use it to load each successive record or to allocate (and presumably
to deallocate) a database record dynamically upon each iteration of the
loop.
Personally, I would have misgivings about reusing a single object over
multiple records. It's obviously crucial that stray fields from a
previous record don't linger and make it into the next. To prevent such
a problem, the app must reinitialize the record each time through the
loop. That being the case, it just seems easier and more certain to
construct a new record rather than to recycle an old one.
Furthermore, the fact that reusing a record is at all feasible implies
that a record constructed for each iteration does not have to be
constructed on the heap. Instead it should be possible to declare and
initialize the db record object locally, since it will not survive past
the next iteration anyway. Allocating the record on the stack avoids
the expense of dynamic allocation and reduces the difference between
the two approaches to be the difference between reinitializing the
record or statically constructing it each time through the loop. The
performance difference between those two options should not be
significant; so the "correct" approach may not have to prove any more
costly.
Greg
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Daniel M. Pfeffer Guest
|
Posted: Fri Dec 16, 2005 1:50 pm Post subject: Re: private default constructor is good or bad? |
|
|
"swengtoo" <swengtoo (AT) my-deja (DOT) com> wrote
| Quote: | In his book "More Effective C++", Scott Meyer suggests in "Item 4" to
"Avoid gratuitous default constructors".
To summarize his claims against default constructors for "the right
classes" he states that:
|
[Quote about inappropriate default constructors snipped]
| Quote: | Now... I tried to follow this guideline (among others), by declaring a
private default constructor for a class that seems to be useless
without being properly initialized with some values.
|
There is no need to declare a private default constructor. A
compiler-created default constructor will only be created if the class has
no other constructors.
| Quote: | However, this created a problem of inability to optimize my application
for speed. The reason is that in my particular case I am re-creating a
database record (represented by the aforementioned class with private
ctor) on the heap in a pretty huge loop. The call to 'new' is very
costly in terms of CPU cycles... I realized I can improve performance
greatly if I instantiate this record only once *outside* the loop.
However, outside the loop I don't have any meaningful values to
initialize that record with, so a default constructor seems to be
required here...
|
1. Does the elegant program meet the quality bars (for speed, memory, etc)?
If it does, your work is done.
2. Don't neglect the possibility that a change of algorithm may solve your
problem without sacrificing elegance.
3. [A simple speed optimisation] If your database entry class is not too
large, why not declare it on the stack, rather than call new/delete? That
would eliminate both the need for the call to new and the need for the call
to delete. Your constructor (and destructor) would still be called once per
loop, but you would eliminate the overhead of the memory allocation.
4. [Less elegant] You might want to initialise your database entry instance
with the first record outside the loop, and then rearrange the loop as
follows:
// read first entry
CDBentry *pEntry = new CDBentry(/* ... */);
while (true)
{
// process DB entry
if ( /* test if done */ )
break;
// read next entry into pEntry
}
delete pEntry;
| Quote: | So, my question is: how do I solve the dilemma? On one hand, from the
*logical correctness* point of view, it doesn't make sense for my class
to have a default constructor. On the other hand, from *performance*
point of view a default constructor is required (or using some dummy
values for the non-default ctor, which is basically the same).
Can performance considerations justify violation of "elegant
implementation"?
|
It depends what the performance bar is for your program. Elegant code is
typically much more maintainable, therefore I usually code the "elegant"
solution first. Only if the elegant solution is insufficient (because of the
speed, the memory, or other quality bars) do I try optimisation using
non-elegant solutions. Remember that premature optimisation is the root of
all evil!
HTH
Daniel Pfeffer
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
swengtoo Guest
|
Posted: Fri Dec 16, 2005 4:53 pm Post subject: Re: private default constructor is good or bad? |
|
|
Daniel (and all others) - thanks for your replies. I agree with all
your comments. In fact, those are thoughts that I had before even
posting, but they were not as neatly organized as yours.
So, if I understand your point(s) correctly, you do agree that a
default constructor for a class that does not *conceptually* justify
it, should be avoided as much as possible. Did I understand all of you
correctly?
BTW, MFC and wxWidgets are two examples of very popular (and useful)
class libraries that do not follow this guidline.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Matthias Hofmann Guest
|
Posted: Sat Dec 17, 2005 10:58 am Post subject: Re: private default constructor is good or bad? |
|
|
"swengtoo" <swengtoo (AT) my-deja (DOT) com> schrieb im Newsbeitrag
news:1134749880.509359.250180 (AT) z14g2000cwz (DOT) googlegroups.com...
[snip]
| Quote: | BTW, MFC and wxWidgets are two examples of very popular (and useful)
class libraries that do not follow this guidline.
|
Popularity does not imply quality.
--
Matthias Hofmann
Anvil-Soft, CEO
http://www.anvil-soft.com - The Creators of Klomanager
http://www.anvil-soft.de - Die Macher des Klomanagers
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
sid Guest
|
Posted: Sat Dec 17, 2005 11:03 am Post subject: Re: private default constructor is good or bad? |
|
|
| Quote: | Can performance considerations justify violation of "elegant implementation"?
In my opinion yes. |
In your case you seem to be using the class object as a temp object
either for the reading or writing. Is your performance problem truly
from new/delete or from not reading/writing in batch to the db? I've
never seen a case where the deallocation is significant compared to the
reading/writing time.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Bob Bell Guest
|
Posted: Sun Dec 18, 2005 12:38 pm Post subject: Re: private default constructor is good or bad? |
|
|
swengtoo wrote:
| Quote: | In his book "More Effective C++", Scott Meyer suggests in "Item 4" to
"Avoid gratuitous default constructors".
To summarize his claims against default constructors for "the right
classes" he states that:
|
[snip]
| Quote: | Now... I tried to follow this guideline (among others), by declaring a
private default constructor for a class that seems to be useless
without being properly initialized with some values.
However, this created a problem of inability to optimize my application
for speed. The reason is that in my particular case I am re-creating a
database record (represented by the aforementioned class with private
ctor) on the heap in a pretty huge loop. The call to 'new' is very
costly in terms of CPU cycles... I realized I can improve performance
greatly if I instantiate this record only once *outside* the loop.
|
If you only need one record, why are you dynamically allocating it?
Bob
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Michiel.Salters@tomtom.co Guest
|
Posted: Mon Dec 19, 2005 2:45 pm Post subject: Re: private default constructor is good or bad? |
|
|
swengtoo wrote:
| Quote: | ... in my particular case I am re-creating a
database record (represented by the aforementioned class with private
ctor) on the heap in a pretty huge loop. The call to 'new' is very
costly in terms of CPU cycles... I realized I can improve performance
greatly if I instantiate this record only once *outside* the loop.
|
You could also move just a malloc outside the loop, and use placement
new inside (instead of an assignment). This localizes the exception to
the rule, but the generated assembly is probably (almost) the same.
HTH,
Michiel Salters
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|