By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,305 Members | 1,614 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,305 IT Pros & Developers. It's quick & easy.

best C++ solution? (fwd decl, circular ref)

100+
P: 293
How can I call a.Print() from a.b.Recurse()? Adding a pointer in b.Recurse(A *ptr) causes undeclared errors, and adding a forward declaration was an invalid type of forward declaration. I copied an example using header files, and the forward declaration problem still existed. I used both Cygwin and Mingw compilers.

Obviously, this is a simplified example. One solution is to nest class B within class A. However, in my actual code, class A has a vector of class B. I just tested it, that would work fine, but is there a better way to solve this?

Example code
Expand|Select|Wrap|Line Numbers
  1. #include <iostream.h>
  2. #include <stdlib.h>
  3.  
  4. class B
  5. {
  6. public:
  7.   void Recurse()
  8.   {
  9.     this->Print(); // want a.Print(), not b.Print()
  10.   }
  11.  
  12.   void Print()
  13.   {
  14.     cout << "B" << endl;
  15.   }
  16. };
  17.  
  18. class A
  19. {
  20.   public:
  21.   B b;
  22.  
  23.   void Recurse()
  24.   {
  25.     b.Recurse();
  26.   }
  27.  
  28.   void Print()
  29.   {
  30.     cout << "A" << endl;
  31.   }
  32. };
  33.  
  34. int main()
  35. {
  36.     A a = A();
  37.     a.Recurse();
  38.  
  39.     system("PAUSE");
  40.     return 0;
  41. }
Jun 20 '06 #1
Share this Question
Share on Google+
2 Replies


Banfa
Expert Mod 5K+
P: 8,916
The mistake you are making is putting your class code into the class definition. If you define the class separately to where you put the class code then you will be able to successfully make a forward reference to class A without causing errors

Expand|Select|Wrap|Line Numbers
  1. #include <iostream.h>
  2. #include <stdlib.h>
  3.  
  4. class A;
  5.  
  6. class B
  7. {
  8. public:
  9.   void Recurse(A &a);
  10.   void Print();
  11. };
  12.  
  13. class A
  14. {
  15.   public:
  16.   B b;
  17.  
  18.   void Recurse();
  19.   void Print();
  20. };
  21.  
  22. void B::Recurse(A &a);
  23. {
  24.   a.Print(); // want a.Print(), not b.Print()
  25. }
  26.  
  27. void B::Print()
  28. {
  29.   cout << "B" << endl;
  30. }
  31.  
  32. void A::Recurse()
  33. {
  34.   b.Recurse(*this);
  35. }
  36.  
  37. void A::Print()
  38. {
  39.   cout << "A" << endl;
  40. }
  41.  
  42. int main()
  43. {
  44.     A a = A();
  45.     a.Recurse();
  46.  
  47.     system("PAUSE");
  48.     return 0;
  49. }
  50.  
I haven't tested/compiled this code, but the principle is sound. This works because during the class definition all B needs to know is that class exists, it does not need to know what members it has. It only needs to know what members it has during the implementation of it's methods which it does once the code is re-written like this.
Jun 21 '06 #2

100+
P: 293
D_C
Thank you.
Jun 22 '06 #3

Post your reply

Sign in to post your reply or Sign up for a free account.