ronen@cit-vax.Caltech.Edu (Ronen Barzel) (04/11/90)
WHAT DO I WANT?
An extra capability in C++: the ability to specify initializations
for class members within the class definition, as part of the member
declaration. Thus, for example, I would like the following to be legal:
OLD NEW
---------------------- ------------------------------
class A { class A {
char *ptr; char *ptr = 0;
const int n; const int n = 3;
class B &bref; class B &bref = * new class C;
double f; double f = 1.5;
int i; int i;
A(); A();
A(int); A(int);
}; };
A::A() : A::A()
ptr(0), n(3), { /* body */ }
bref(* new class C),
f(1.5)
{ /* body */ }
A::A(int j) : A::A(int j) : i(j)
ptr(0), n(3) { /* body */ }
bref(* new class C),
f(1.5),
i(j)
{ /* body */ }
Essentially, the compiler would prepend the class-specified initializations
to whatever is listed in the constructor initialization list.
WHY DO I WANT THIS?
Three related reasons:
a. I often have pointer members that I want initialized to 0
(e.g. "ptr" above); it's easiest to just specify the 0 where
the pointers are declared.
b. More generally, it seems cleaner to be able to specify the
initialization of a variable in the same place it's declared;
as is, if I change around what the members of a class, I then
have to go somewhere else in the file to update the initializations.
c. Most important: When a class has several constructors, the
initialization must be duplicated for each constructor; this is
clearly error-prone, since any changes must be repeated for each
constructor. To minimize the problems, I often write code like this:
#define A_INIT ptr(0), n(3), B(* new class C), f(1.5)
A::A() : A_INIT { ... }
A::A(int j) : A_INIT, i(j) { ... }
A::A(char *s) : A_INIT { ... }
This seems a little klunky, however.
COROLLARY ISSUES:
Some relatively minor questions arise.
a. Order of initialization? Perhaps the initializations would
happen in order of appearance. It would be nice if the result
of an earlier initialization could be used in a later one.
b. Overriding initializations via the member initialization list?
If a constructor tries to initialize something that has an initialization
in the class definition, it could be considered illegal; more convenient,
however, might be to have the new initialization override. E.g.
OLD NEW
---------------------- ------------------------------
A::A(int m, int j) : A::A(int m, int j) : n(m), i(j)
ptr(0), n(m), { /* body */ }
bref(* new class C),
f(1.5),
i(j)
{ /* body */ }
c. Scope for expressions? I guess the scope would be the same as for
the member initialization list of a constructor with no arguments:
i.e. "this", class members, and file-scope items.
COMMENTS:
This feature seems to me to have everything going for it -- it's useful,
backwards compatible, doesn't add new syntax, ought to be easy to implement.
Before I twist my arm patting myself on the back, how do all of you "out there"
feel about it? Comments, counter-proposals? Am I a dope? Is this old hat?
Does Brand X C++ already support this?
-Ronen Barzel
ronen@csvax.caltech.edu
ronen@cit-vax.Caltech.Edu (Ronen Barzel) (04/11/90)
In article <14560@cit-vax.Caltech.Edu> I write: > ...the ability to specify initializations >for class members within the class definition, as part of the member >declaration.... > >Does Brand X C++ already support this? I have been told that g++ supports this feature. Out of curiousity, are there any other C++ implementations that support enchancements (or other language differences) over the AT&T2.0/Stroupstrup/Lippman standard? -Ronen
horstman@sjsumcs.sjsu.edu (Cay Horstmann) (04/13/90)
In article <14560@cit-vax.Caltech.Edu> ronen@cit-vax.Caltech.Edu (Ronen Barzel) writes: >WHAT DO I WANT? > >An extra capability in C++: the ability to specify initializations >for class members within the class definition, as part of the member >declaration. Thus, for example, I would like the following to be legal: > > > OLD NEW > ---------------------- ------------------------------ > class A { class A { > char *ptr; char *ptr = 0; > const int n; const int n = 3; ... > A(); A(); > A(int); A(int); > }; }; ... I don't think this is so great. The only benefit would be to give the compiler a hint to factor out code common to all constructors. But you could do that manually with a member function. HOWEVER, for static const this would indeed be very desirable: class Table { static const int SIZE = 20; Whatnot* t[ SIZE ]; // ... }; Whatever you do, please do not post back that I could use a local enum { SIZE = 20 }. Cay
ronen@cit-vax.Caltech.Edu (Ronen Barzel) (04/14/90)
In article <1990Apr13.064548.1133@sjsumcs.sjsu.edu> horstman@sjsumcs.SJSU.EDU (Cay Horstmann) writes: > ...The only benefit would be to give the >compiler a hint to factor out code common to all constructors. But you >could do that manually with a member function. You can't do it in all cases. From Lippman, sec 6.1 p.243: "The member initialization list is the only mechanism by which const and reference class data members can be initialized." Thus const and reference initializations can't be factored out into a member function. >HOWEVER, for static const this would indeed be very desirable: I agree. Even for static but non-const. In summary, I think it's desirable to specify an initialization for anything as part of (or at least along with) its definition. [Anybody care to argue with this claim?] Along the same lines, it would be nice to specify default parameters to base class constructors. Again, this is something that can't be factored out into a member function. e.g.: OLD NEW ---------------------- ------------------------------ class A : public B { class A : public B(3,"foo") { A(); A(); }; }; A::A() : B(3,"foo") A::A() { /* body */ } { /* body */ } Does g++ support this too? -Ronen