[comp.lang.c++] constructors and initializers

rae@alias.com (Reid Ellis) (05/08/91)

A note about initializers in constructors.  Recently, the following
class was mentioned under the subject line "HELP: default constructor
for array of class":

	class Point {
		int x;
	public:
		Point() { x = 200; }
		Point(int xc = 100) { x = xc; }
	};

Not to belabor the point [pun intentional] but the constructors should
be written as:

	class Point {
		int x;
	public:
		Point() : x(200) {}
		Point(int xc = 100) : x(xc) {}
	};

i.e. use initializers rather than assignment in a constructor.  Why?
The following line of code won't work with the first version, but will
work with the second version:

	const Point kPoint(23);

I just thought I'd mention this since I see assignment in constructors
in several examples people post here [not just "Point" :-)].

If this is imperious and sounds like I'm pontificating, feel free to
send me mail saying so. :)
					Reid, a.k.a. "Mister nit pick"
--
Reid Ellis
rae@utcs.toronto.edu        ||               rae@alias.com
CDA0610@applelink.apple.com ||      +1 416 362 9181 [work]

sdm@cs.brown.edu (Scott Meyers) (05/09/91)

In article <1991May8.155352.18313@alias.com> rae@alias.com (Reid Ellis) writes:
| A note about initializers in constructors.  Recently, the following
| class was mentioned under the subject line "HELP: default constructor
| for array of class":
| 
| 	class Point {
| 		int x;
| 	public:
| 		Point() { x = 200; }
| 		Point(int xc = 100) { x = xc; }
| 	};
| 
| Not to belabor the point [pun intentional] but the constructors should
| be written as:
| 
| 	class Point {
| 		int x;
| 	public:
| 		Point() : x(200) {}
| 		Point(int xc = 100) : x(xc) {}
| 	};
| 
| i.e. use initializers rather than assignment in a constructor.  Why?
| The following line of code won't work with the first version, but will
| work with the second version:
| 
| 	const Point kPoint(23);

But it will work.  It's perfectly acceptable to invoke constructors (and
destructors) on const objects -- see the ARM section 9.3.1, p. 178.

Although the ARM doesn't explicitly say it anywhere, it seems to be the
case that a const object doesn't become const until after construction is
complete (including the body of the constructor), and it ceases to be const
once destruction commences.  This seems to me to be the only practical
semantics, since you can't always do everything you want to through the
member initialization list.

For the more empirical in the audience, the above code also compiles
and runs under cfront 2.0, 2.1, and g++ 1.39.

Scott

-------------------------------------------------------------------------------
What do you say to a convicted felon in Providence?  "Hello, Mr. Mayor."

mwb@ulysses.att.com (Michael W. Balk) (05/12/91)

In article <1991May8.155352.18313@alias.com>, rae@alias.com (Reid Ellis) writes:
|  A note about initializers in constructors.  Recently, the following
|  class was mentioned under the subject line "HELP: default constructor
|  for array of class":
|  
|  	class Point {
|  		int x;
|  	public:
|  		Point() { x = 200; }
|  		Point(int xc = 100) { x = xc; }
|  	};
|  
|  Not to belabor the point [pun intentional] but the constructors should
|  be written as:
|  
|  	class Point {
|  		int x;
|  	public:
|  		Point() : x(200) {}
|  		Point(int xc = 100) : x(xc) {}
|  	};
|  
|  i.e. use initializers rather than assignment in a constructor.  Why?
|  The following line of code won't work with the first version, but will
|  work with the second version:
|  
|  	const Point kPoint(23);


Using Cfront 2.1 and the first definition of class Point above (the one with
assignment in the constructors), I have no trouble compiling a main that
creates const Point kPoint(23).  And, Point::x actually gets the value 23
in the definition of kPoint when I add a print member function to examine it.

	Mike Balk
	AT&T Bell Laboratories
	Murray Hill, NJ 07974
	mwb@ulysses.att.com