Thread: Getting classes to reference each other

  1. #1
    Registered User
    Join Date
    Jan 2003
    Posts
    42

    Getting classes to reference each other

    I have two classes which I store in seperate files.
    Class A has functions that use class B as a parameter.
    Class B has functions that use class A as a parameter.

    I can't seem to get them to compile. I've tried including them in each other, but this only puts the compiler into an infinite loop (until it complains about it and terminates). It's really frustrating. I'm sure there's an easy way to do it that I don't know about...

    I'm relatively new to C++. I learned Java as my first language in college (they teach it because of its simplicity), and then C (which was a horribly painful transition, but I managed to get a 100 on both C programming assignments) near the end the class I just finished. I'm learning the differences between C and C++ on my own over the winter break. Other than stuff like this, my C to C++ transition has been pretty smooth.

  2. #2
    I think you can predefine a class like a function

    #include "A.h"

    class A;

    class B{
    ....
    };
    My Avatar says: "Stay in School"

    Rocco is the Boy!
    "SHUT YOUR LIPS..."

  3. #3
    Registered User
    Join Date
    Jan 2003
    Posts
    42
    If I put "#include A" in B and "#include B" in A, the compiler starts an infinite loop (which it terminates on its own eventually and then yells at me).

    These classes were previously all in one file and worked fine, but the clutter was so annoying that I stuck them neatly in their own files. Now they're annoyed and don't seem to know about each other.

  4. #4
    Registered User
    Join Date
    Dec 2002
    Posts
    119
    You need four files:

    a.h and b.h define class a and class b in these two files and use preprrocessor directives to make sure they're only included once:
    Code:
    // a.h
    #ifndef MYCLASSA_H
    #define MYCLASSA_H
    class a{
    public:
        a();
        ~a();
        // other fuctions
    private:
        // data members
    };
    #endif
    // then you need two files to implement the functions for the classes:
    example:
    Code:
    // a.cpp
    
    #inlcude "a.h"
    #inlcude "b.h"
    
    a::a()
    {
        // constuctor
    }
    
    a::~a()
    {
        // destructor
    }
    
    // end of file
    be sure to inlcude both a.h and b.h in both of you .cpp files and that should solve your probem

    -Futura
    If you speak or are learning Spanish, check out this Spanish and English Dictionary, it is a handy online resource.
    What happens is not as important as how you react to what happens. -Thaddeus Golas

  5. #5
    Registered User
    Join Date
    Jan 2003
    Posts
    42
    Thanks! It looks like that's worked. I still have a few changes to make with my code because the classes aren't accessing my previously global variables, so I have to make a few changes. But I don't see a single complaint about the class definitions!

  6. #6
    Registered User
    Join Date
    Jan 2003
    Posts
    42
    Unfortunately, it worked in the context I was talking about, but my actual program has several more classes, most of which contain references to some other class. Thanks to this, no matter what order I place the "#include"s in, it refuses to work.

    I'm going to try to see if I can use one class to manage communication between the other classes. Hopefully this will work, or I'll have to rewrite the entire program.

  7. #7
    ....
    Join Date
    Aug 2001
    Location
    Groningen (NL)
    Posts
    2,380
    >Thanks to this, no matter what order I place the "#include"s in,
    >it refuses to work.

    Not quit sure about the situation, but if I understand you well you have several files with classes and each class is defined in a seperate header-file. In that case you must make sure that each file with a class includes the necessary other headerfiles.

    It could also mean that your classes have too much dependencies on eachother, so a design improvement would be recommendable.

  8. #8
    Registered User
    Join Date
    Dec 2002
    Posts
    119
    >Thanks to this, no matter what order I place the "#include"s in,
    >it refuses to work.


    Hope is not lost. Make one .cpp and one .h file for each class. Then make one grand .h file "all.h" in which you just #inlcude all the .h files. Then include all.h in all of your implementation files (.cpp). This will work if you have your includes in all.h in the "right order" (the order they're used) You may also consider some design improvements as mentioned by Shiro

    -Futura
    If you speak or are learning Spanish, check out this Spanish and English Dictionary, it is a handy online resource.
    What happens is not as important as how you react to what happens. -Thaddeus Golas

  9. #9
    Registered User
    Join Date
    Jan 2003
    Posts
    42
    It seems that Shiro is right. I can't order it in a way that will satisfy the compiler because of the rampant calling of other classes. It simply refuses to work.

    However, they don't actually have to communicate with each other directly. Every instance of the classes I'm using has a reference stored to it in a bunch of arrays. I can use the array index numbers to designate a particular object instead of using the actual reference, and then using the reference in the array. I can let either my "main file" or a seperate class do that, hopefully.

    So it would be something like this:
    - Classes A, B, C, D, E, etc. all contain a reference to an object of the class MEGACOOL (probably a singleton) that handles communication between them. They'll contain references to no other objects besides MEGACOOL.
    - Class MEGACOOL contains the arrays of references to instances of A, B, C, D, E, etc. It also has all the methods required to facilitate smooth communication.

    Does that sound workable? If it's a dumb idea, does anyone have a better suggestion?

  10. #10
    ....
    Join Date
    Aug 2001
    Location
    Groningen (NL)
    Posts
    2,380
    I don't see why you would need a class to handle communication between the classes, but maybe that's also because the problem is not very clear to me.

    Maybe another solution:

    Make an abstract class and derive all your classes from it. Then make the arrays being arrays of pointers to that abstract class. So you can let the pointers point to whatever derived class.

    In your methods you can then accept arguments of type abstract class, so your methods don't depend on the specific derived classes. Then you only need to include the abstract class definition and don't depend anymore on the specific derived classes.

    [edit]
    Your solution with MEGACOOL looks a bit like mine, but it has a disadvantage, it needs to know about the other classes. Which makes it depending on the other classes.
    [/edit]
    Last edited by Shiro; 01-04-2003 at 04:47 AM.

  11. #11
    Registered User
    Join Date
    Jan 2003
    Posts
    42
    I still have the old version of my source code, which I saved just before I seperated the classes into several files. Looking back, it's pretty messy. But if you look at the functions for each class, you'll notice that several functions that reference other classes in some way. Maybe it's my lack of experience with C++ classes (I adore classes, though, and have ever since I first learned Java), but I got lost very quickly when I split them up.

    When I organized the classes into their own .h and .cpp files, the compiler started going nuts. That's when I made my first post. I couldn't figure out an organization for the "#include"s that would make it work. And even then, it would probably be poor coding if I have to worry so much about the order in the first place.

    This is a simple text based RPG I've been working on for the past few days. I didn't ask in the games forum because this seems to be more about class organization and less about games.

  12. #12
    Registered User
    Join Date
    Dec 2002
    Posts
    119
    You've got 3 classes Room Character and Item. There is only one dependancy - the Item class requires the Character class.
    // This order should work:
    #include "Room.h"
    #include "Character.h"
    #include "Item.h"

    Something else must be going wrong. What compiler are you using? Have you added all the files to the project?

    -Futura
    If you speak or are learning Spanish, check out this Spanish and English Dictionary, it is a handy online resource.
    What happens is not as important as how you react to what happens. -Thaddeus Golas

  13. #13
    Registered User
    Join Date
    Jan 2003
    Posts
    42
    I'm using Dev-C++.

    It's not very clear at a first glance, but the Character class does access functions in the item class.

    In Character::printInventory():
    Code:
     cout << itemID[inventory[i]]->getName();
    In Room::look()
    Code:
     itemID[items[i]]->getName()
    Because they get seperated into numerous files, I can't access those arrays anymore, and even if I could, I still have to #include several times.

    Right now I'm rebuilding the code piece by piece until I find a way to make it work. The compiler errors are so vague (sometimes I miss Java) that it's quite possible I mistook one to mean something else.
    Last edited by Vorok; 01-04-2003 at 01:12 PM.

  14. #14
    ....
    Join Date
    Aug 2001
    Location
    Groningen (NL)
    Posts
    2,380
    >Right now I'm rebuilding the code piece by piece until I find a
    >way to make it work.

    I haven't taken a look at your code yet, but I still think you need to do some redesign on paper. Rebuilding the code piece by piece and hope that it will work of takes more time than making a new design.

    >Maybe it's my lack of experience with C++ classes

    C++ classes differ not very much from Java classes, except that the Java language itself is a bit more clear, easier to understand, than C++.

    I think it is more a lack of experience with object oriented design.

    [edit]
    From your code it seems that item uses character, by function takenBy. You can simplify your relationships by realizing that both character and room use an item.

    You have stored your items in a global array. So by using your interface-functions setGetable and getGetable a character can then try to get an item. In this way you can make item independent from character and room.
    [/edit]
    Last edited by Shiro; 01-05-2003 at 04:56 AM.

  15. #15
    Registered User
    Join Date
    Jan 2003
    Posts
    42
    You're probably right that my lack of experience was the real source of the problem. I've never written a program of nearly this large a scope before, so my initial preparations were pretty darned shoddy. Also, I actually started writing it in C (the classes were all structs), but then decided to learn about C++ and use that instead. Unfortunately, I was learning as I was going, so I kept changing my code which constantly messed things up. I'm feeling more nestled in with C++ now, so with any luck it should be a lot less harrowing a journey from here. I've gotten past my horrible class problem and another hurdle with an inexplicable problem with loading from my data file (which I fixed by simply scrapping the load function and writing it over again).

    This program is turning out to be a real learning experience. Before I write any more code, I'm sitting down and making sure I plan this out better.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. In over my head
    By Shelnutt2 in forum C Programming
    Replies: 1
    Last Post: 07-08-2008, 06:54 PM
  2. Undefined Reference Compiling Error
    By AlakaAlaki in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 11:45 AM
  3. A general quaetion on portability
    By kris.c in forum C Programming
    Replies: 7
    Last Post: 07-20-2006, 03:48 AM
  4. problem with the library
    By kris.c in forum C Programming
    Replies: 21
    Last Post: 07-10-2006, 08:29 PM