Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sdd.hp.com!elroy.jpl.nasa.gov!cit-vax!ronen From: ronen@cit-vax.Caltech.Edu (Ronen Barzel) Newsgroups: comp.lang.c++ Subject: Class member initialization proposal Message-ID: <14560@cit-vax.Caltech.Edu> Date: 10 Apr 90 22:17:23 GMT Organization: California Institute of Technology Lines: 99 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