TITLE: forward declarations and namespaces Sheetal: svkakkad@cs.utexas.edu (Sheetal V. Kakkad) I have some code where I need to tell the compiler that a class name is valid, without supplying the entire definition of the class. I can do this with a regular class with a forward declaration: class Node; // "Node" is a valid class name below this point // I can now use the symbol "Node" in this file as long as the use // does not require knowledge of size or data members. void func (Node *p); The above would compile without any error messages since "Node" has been declared to be a valid symbol for this compilation unit. Now, consider that the definition of "Node" is nested inside another class, say "List", in a different file. However, the following modification of the previous code is not valid: class List::Node; void func (List::Node *p); One reason I was given is that if this were allowed, it potentially opens a "backdoor" to add/change members in the outer class, without changing the definition. However, since I am not defining the class "List::Node", the usage should be safe (and should be allowed). Steve: clamage@Eng.Sun.COM (Steve Clamage), 11 Feb 96 Perhaps the rule could be relaxed to allow forward declaration of nested class names as you suggest. (OTOH, it's kind of letting the camel's nose into the tent. Exactly how much of the insides of a class should you be able to declare without providing a definition? But I suppose we could say, "Just the nose, and no more.") It seems to me that it is much better programming practice to say #include "myClass.h" than to say class myClass; class myClass::Fee; class myClass::Fie; class myClass::Foe; class myClass::Fum; class myClass::Phooey; So the real question is why you want the language feature. I assume it is to reduce compilation time by reducing the number of header files that have to be processed. And that is really an implementation issue. What you really want, I think, is for compilations to go faster. Some compilers already provide a way to reduce compilation times by precompiing header files. The other problem is the need to recompile everything when a class definition changes. That too is an implementation issue. A development system can be smart enough to figure what needs to be recompiled due to to change and what does not. In addition, systems exist that do not always require recompiling a program when class definitions change -- often old object code can still be linked with code compiled against newer versions of class definitions. Expect to see more systems like this in the future. (That is, the systems relax the One-Definition Rule in well-defined ways to allow some programs to work that would otherwise have undefined behaior.) Finally, you can get the above effect with any implementation if you add a layer of indirection. A class consists only of a pointer to the actual implementation, plus a public interface that almost never changes. Client classes use only the almost-unchanging public interface in the header file, and you can make all the changes you like in the class implementation without having to recompile a client. (Maybe there is a runtime performance hit, but you can save a lot of development time.) So I would rather see the problem of long compilation times addressed by making better implementations, instead of by adding hacks to the language to work around slow implementations. The purpose of a forward declaration is to allow self-referencing or cross-referencing declarations, not specifically to reduce the number of included files. Sheetal: Another question along similar lines is whether the same forward declaration problem occurs with the use of namespaces. Steve: Not really. Unlike a class, a namespace can be opened and closed and added to any number of times, even in one compilation unit. Example: namespace A { class X; }; bool valid(A::X* x) { return x != 0; } Someplace else, in the same compilation unit or in a different one: namespace A { class X { ... }; // definition of X class Y { ... }; // haven't mentioned Y until now };