TIP: Click on subject to list as thread! ANSI
echo: c_plusplus
to: BENJAMIN L MCGEE
from: CLIFF RHODES
date: 1997-08-16 11:14:00
subject: ctors

--> Benjamin L wrote to All  <--
BL>I'd like the opinion of the folks in this echo concerning the
BL>following statement from the book "Black Belt C++..."
BL>C programmers are faced with two temptations in writing
BL>constructors:
BL> 
BL>     o    The temptation to ascribe too much responsibility to
BL>          the constructor.  The constructor's responsibility is
BL>          to "make an object out of a bunch of raw bits."  Just
BL>          that, and no more.  A constructor that has sweeping
BL>          side effects is normally poor programming practice
BL>          because constructors can be called by the compiler
BL>          when you least expect it.  This can introduce exposure
BL>          to buggy behavior or inefficiency.
This is very true. You don't want to cram too much into a constructor, 
it's purpose is to create an instance only.
BL>     o    The temptation to write a constructor to create an
BL>          object of a user defined type from just about any
BL>          other type imaginable.  Conversion by construction is
BL>          not bad, but it is important to define what sort of
BL>          conversions make sense up front.
This is just common sense. You should only provide the conversions 
necessary for the design.
BL>How would you define "ascribing to much responsibility to the
BL>constructor?"
I think that falls into the realm of what is good design. It's 
subjective. For instance, if you had an object that was meant to get 
input from a user, it would be bad design to try to get input in the 
constructor. You would provide a separate method to get the input.
BL>Is this to much.. 
BL>manifest::manifest(){
BL>     filename = new char[FILENAME_MAX];
BL>     while (!select(filename, FILENAME_MAX - 1));
BL>     mstreamp = new ifstream(filename);
BL>}
Not necessarily although it does pose some problems with error 
handling (which you could do with exceptions). Your options are to 
either do this or provide an initialization member (or method) to open 
the stream. I personally don't like classes the require an explicit 
call to Initialize() although that is a widely used approach. If the 
methods that use mstreamp are very few in number, you could hide the 
initialization:
// Simple constructor
manifest::manifest() { filename = 0; mstreamp = 0; }
// Initialization routine
int manifest::init() { filename = new char[FILENAME_MAX];
                       if(!filename) return 0;
                       while(!select(...));
                       mstreamp = new ... 
                       if(!mstreamp) return 0;
                       return 1;  }
// Member that uses mstreamp
int manifest::dosomething() { if(!mstreamp)
                                 if(!init()) return 0;
                              ...
This is more an art than a science, so the best approach is just to 
bear the author's warning in mind. If you can simplify a constructor, 
do so. If you can't just be careful.
Cliff Rhodes
cliff.rhodes@juge.com
crhodes@flash.net
X CMPQwk 1.42 1692 X"What so tedious as a twice told tale?" - Homer
--- Maximus/2 3.01
---------------
* Origin: COMM Port OS/2 juge.com 204.89.247.1 (281) 980-9671 (1:106/2000)

SOURCE: echomail via exec-pc

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.