mh@awds26.imsd.contel.com (Mike Hoegeman) (03/20/90)
This is probably a stupid question, but here goes anyway. how do you set up two classes that refer to each other ? Here's a simple example to demonstrate my problem. class thing { int data[5]; void execute(stack &s) { s.push(this); } } class stack { stack_store thing[500]; int si; private: void push(thing *t); stack() { si = 0; } } void stack::push(thing *t) { stack_store[si++] = *t; } main() { thing mything; stack mystack; mything.execute(); } Now, the question is. How do I properly forward declare class 'stack' to class 'thing' so that everybody is happy ? I have the stroustrup C++ book as well as the Dewhurst/Stark C++ book so an admonishing "you'll find this on page <n> in Stroustrup you moron" is fine :-). I've scanned through these two books but have not found the answer. thanks, - mike hoegeman, mh@wlbr.imsd.contel.com
rfg@ics.uci.edu (Ronald Guilmette) (03/20/90)
In article <49689@wlbr.IMSD.CONTEL.COM> mh@awds26.UUCP (Mike Hoegeman) writes: > >This is probably a stupid question, but here goes anyway. how do you >set up two classes that refer to each other ? Here's a simple example >to demonstrate my problem. > > > class thing { > int data[5]; > void execute(stack &s) { > s.push(this); > } > } > > class stack { > stack_store thing[500]; > int si; > private: > void push(thing *t); > stack() { > si = 0; > } > } > > void > stack::push(thing *t) { > stack_store[si++] = *t; > } > > main() { > thing mything; > stack mystack; > > mything.execute(); > } > >Now, the question is. How do I properly forward declare class 'stack' >to class 'thing' so that everybody is happy ? Declare: class stack; before the declaration of class "thing". Then move the body of the function thing::execute out of the "thing" class declaration and put it after the class declaration for class "stack". >I have the stroustrup C++ book as well as the Dewhurst/Stark C++ book >so an admonishing "you'll find this on page <n> in Stroustrup you >moron" is fine :-). I've scanned through these two books but have not >found the answer. You'll find this on page <n> in Stroustrup you moron. :-) (Sorry. I couldn't resist. :-) // Ron Guilmette (rfg@ics.uci.edu) // C++ Entomologist // Motto: If it sticks, force it. If it breaks, it needed replacing anyway.
gbaciu@watcgl.waterloo.edu (George Baciu [CGL]) (03/21/90)
In article <49689@wlbr.IMSD.CONTEL.COM>, mh@awds26.imsd.contel.com (Mike Hoegeman) writes: > > This is probably a stupid question, but here goes anyway. how do you > set up two classes that refer to each other ? Here's a simple example > to demonstrate my problem. ..... example changed for correct compilation below..... > > Now, the question is. How do I properly forward declare class 'stack' > to class 'thing' so that everybody is happy ? > > - mike hoegeman, mh@wlbr.imsd.contel.com This is a real problem in C++ and it is reminiscent of early implementations of Pascal. Now, most Pascal compilers have a "forward" keyword which allows circular declarations of procedural blocks. I wish C++ would provide the same sort of facility in the next releases. Now, in order to deal with circular declarartions in C++ I had to do the following: 0. declare the names of all the classes involved, as class x; class y; 1. data members of type class can only be references or pointers but NOT objects. 2. all the inline functions, implementing the methods containing the member classes involved, must follow the declarations of all the classes involved; this implies that you must have only the prototype declarations of the methods within the class itself. For your example, the following change should work: ------------------------------ cut here -------------------------------- class thing; class stack; class thing { int data[5]; public: void execute(stack&); // implemented after all classes }; class stack { thing stack_store[500]; int si; public: void push(thing *t); // this may be implemented here since stack() { si = 0; } // class thing is already declared. }; void stack::push(thing *t) { stack_store[si++] = *t; } void thing::execute(stack &s) { s.push(this); } main() { thing mything; stack mystack; mything.execute(mystack); } ------------------------------ cut here -------------------------------- Note, that the changed code compiles correctly with cfront 2.0. -- George Baciu ------------------------------------------------- | GBaciu@watcgl.Waterloo.edu GBaciu@watcgl.UWaterloo.CA | | * Computer Graphics Lab * | | University of Waterloo - Waterloo, Ontario, Canada - N2L 3B5 | ------------------------------------------------------------------
jpw@bagend.UUCP (Parnell Watkins) (03/22/90)
In article <49689@wlbr.IMSD.CONTEL.COM> mh@awds26.UUCP (Mike Hoegeman) writes: > >Now, the question is. How do I properly forward declare class 'stack' >to class 'thing' so that everybody is happy ? > The answer is quit simple but I haven't seen it anywhere either ( I wasn't particularly looking). I just borrowed from C. class Foo { friend class Bar; ... }; class Bar { friend class Foo; ... }; The order of the class declarations is no longer a concern. Forward declarations are made by the use of the keyword class. J. Parnell Watkins, Jr. gatech![rebel|galbp]!dkstar!jpw Atlanta, Ga. 30243 gatech!bagend!jpw "The country of Colombia...has over twice as many species of birds as the continental United States though it is only one-seventh the size." ---John S. Dunning, Portraits of Tropical Birds
pcg@odin.cs.aber.ac.uk (Piercarlo Grandi) (03/23/90)
In article <49689@wlbr.IMSD.CONTEL.COM> mh@awds26.imsd.contel.com (Mike Hoegeman) writes: This is probably a stupid question, but here goes anyway. how do you set up two classes that refer to each other ? Another heathen that does not hold my excessively precious advice as sacred :-)! If you write all your member functions *after* the class definition, a lot of problem disappear. You may also need to forward declare the classes, of course (if you use the typedef style names). The general scheme is: struct c1; /* forward declarations */ struct c2; struct ...; struct c1 { int m1; c2 *m2; int p1(int); friend f1(c2 &,char); ... }; struct c2 { double m1; c1 m2; double p1(double); friend f2(c2 &,short); ... }; ... int c1::p1(int i) { ... } int f1(c2 &o, char c) { ... } double c2::p1(double d) { ... } int f2(c2 &o,short s) { ... } ... Notice that of course you *cannot* have two classes that inherit from each other or that appear as fields in each other; true recursive definitions are not allowed. -- Piercarlo "Peter" Grandi | ARPA: pcg%cs.aber.ac.uk@nsfnet-relay.ac.uk Dept of CS, UCW Aberystwyth | UUCP: ...!mcvax!ukc!aber-cs!pcg Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk
Lindsay.Marshall@newcastle.ac.uk (Lindsay F. Marshall) (03/26/90)
Just to be awkward, can anybody suggest a legal way of doing the following :- class B; class A { public: A(); void fa(void (*B::fb)()); }; class B { public: B(); void fb(void (*A::fa)()); }; CC 2.0 gives syntax errors when you try to do this, g++ 1.37.1 gives reasonable error messages. I don't know why you might want to do this, but I'm sure someone out there will want to do it some time. Lindsay -- MAIL : Lindsay.Marshall@newcastle.ac.uk (UUCP: s/\(.*\)/...!ukc!\1/) POST : Computing Laboratory, The University, Newcastle upon Tyne, UK NE1 7RU VOICE: +44-91-222-8267 FAX: +44-91-222-8232
rfg@ics.uci.edu (Ronald Guilmette) (03/28/90)
In article <1990Mar26.115427.14031@newcastle.ac.uk> Lindsay.Marshall@newcastle.ac.uk (Lindsay F. Marshall) writes: >Just to be awkward, can anybody suggest a legal way of doing the >following :- > > class B; > > class A > { > public: > A(); > > void fa(void (*B::fb)()); > }; > > class B > { > public: > B(); > > void fb(void (*A::fa)()); > }; > >CC 2.0 gives syntax errors when you try to do this... As well it should. It seems that you have the *'s in the wrong places. Try using these function declarations instead: void fa(void (B::*fb)()); void fb (void (A::*fa)()); >g++ 1.37.1 gives reasonable error messages. I'd like to know how you define "reasonable". g++ certainly doesn't allow such things, either when they are written with correct syntax or not. When written incorrectly (as shown in your example) I have no idea what g++ will say. When written with correct syntax, g++ will probably just say "syntax error". // Ron Guilmette (rfg@ics.uci.edu) // C++ Entomologist // Motto: If it sticks, force it. If it breaks, it needed replacing anyway.