How To: Make Classes Include Eachother (or achieve the same effect)

Started by
16 comments, last by neonfaktory 20 years, 11 months ago
Ok, I've tried in multiple places to find this answer and it always gets skimmed over or a pre-recorded response (seems like it) or abstracted and ultimately not answered. SO, I'm not even going to post any of my code, I would just like to know the DEFINATIVE way, if possible, to have classes inlcude eachother. The result I would like is to take Class A and inlcude Class B so that I can access Class B's members from within Class A, and then take Class B and include Class A as well, so I may access Class A's members from within Class B. Being able to do so would simplify my program and get rid of this headache, so any help on this would be greatly appreciated . [edited by - neonfaktory on May 1, 2003 11:31:04 AM]
weee!
Advertisement
I think you wanna make them friend classes, so :


  class A;class B{private:  // some data memberspublic:  // some functions  friend class A;};class A{private:  // some other stuffpublic:  // some other functions  friend class B;};  


I think that should work.


you can only include class B in class A, or vice versa, through pointers. You can''t include an object of class B in class A if B is not yet defined.
class A;class B;class A{    B   hello;   // error, compiler doesn''t know how big B is    B*  phello;  // OK};class B{    A   world;   // OK, A has been defined before    A*  pworld;  // OK}; 


Current project: A puzzle game.
% completed: ~0%
Status: Active.
Oops, I should have mentioned "without forward declaration". Forward declaration isn't enough, because whichever class is using the forward declaration doesn't really have full access like inlcuding does. As far as I've been able to achieve, whichever class gets the forward declaration can only get a pointer to a member of the forward declared class, and even then it can't even use the member functions of that class. I have to use some "abstracting" class that has access to both the classes just to be able to manipulate and use the information. Thanks for the response, though. I'm really just looking for an 'absolute include' here, forward decs dont seem to cut it, unless I'm using them incorrectly...

*EDIT* In response to Moagly's code, I didn't notice the "friend" keyword/line in there - does that change the way forward declarations work somehow? I'm not familiar with it *goes to look it up*...

*EDIT* Well, I just looked it up and, from the SOUNDS of it, by "friending" the classes together should allow me to use the data members how I want to. If this is the case, thanks a ton, if not... umm, I'll be back

[edited by - neonfaktory on May 1, 2003 11:42:47 AM]

[edited by - neonfaktory on May 1, 2003 11:46:26 AM]
weee!
The size of an object created by a class is related to the size of its member variables. If A contains B and B contains A then you can't determine the size. If A is made up of B and some extra bit (xa) then:

sizeof(A) = sizeof(B) + xa

If B is made up of A plus some extra bits (xb) then:

sizeof(B) = sizeof(A) + xb
i.e.
sizeof(B) = sizeof(B) + xb + xa
This is recursive and will go on forever. Your compiler won't like it as it needs to know the size of classes to be able to assign memory, dereference pointers, etc, etc. All of that has to be known at compiler time.

I'm not really sure how you're imagining these two classes interacting. Do you mean one class can use the static functions of another class. For there to be any more meaningful relationship you have to be talking about a particular instance of class A communicating with another particular instance of class B.

Are you talking about classes or class instances (ie objects)? Do you have a java background and think you can use inner classes?


[edited by - petewood on May 1, 2003 11:56:25 AM]
Classes that need to talk to each other is usually a sign that another class is needed.

Read Effective C++ and More Effective C++.
Oh, I totally understand the reasons why you can''t LITERALLY do it. I was just wondering if there was some way to achieve the same effect of having access to eachother''s members equally. Now that I THINK I have the answer (using friend declarations), I''ll tell you what I''m trying to do...

I have a "Player" class that handles YOU, as the, well, player. For example, it accepts the input that a different Input class extracted and then passes it on to the Ship class as simplified commands like "THRUST" or "SHOOT".

So, "Player" obviously has to include Ship so it can "AddControl()" and so on, but the problem comes when "Ship" needs to know of some information the Player class is holding; Namely, the Player class holds the custom statistics information, like the Max Health, Shields, Speeds, etc., since each Player will have thier own custom attributes.

Naturally, you would include "Player" in "Ship" so you use Ship member function "Player* myPlayer" to be like "myPlayer->MAX_HEALTH.value" for special calculations that Ship handles, like recharging health to the max level that Player has. However, this wouldnt work because "Player" already has "Ship" included so it can "control" your Ship accordingly.

Simple forward declaration doesn''t seem to work either. I *CAN* have a "Ship" member function "Player* myPlayer", but (I assume) because "Player" isn''t truely included in Ship, I can''t say "myPlayer->MAX_HEALTH.value". So... this means I have to do a simple "recharge" calculation in a different area that has both "Player" and "Ship" included, which is real messy not to mention cumbersome.

Now, if I understand this correctly, I can befriend the classes while using forward declaration and the classes will have access to eachother''s members like I''m hoping? Please say yes
weee!
It can be done, you have to partition your code correctly into header and implementation files:

in A.h:


    class B; // fwd declarationclass A {  // everything in here...  B* m_pB;public:  void doSomethingToB();};  


in B.h:


  class A; // fwd declarationclass B {  // everything in here...  A* m_pA;public:  void doSomethingToA();};  


Then inside A.cpp:


  #include "B.h"void A::doSomethingToB() {  // do your bidness...}  


Similarly for B.cpp:


  #include "A.h"void B::doSomethingToA() {  // do your bidness...}  


Regards,
Jeff

Edit: farging source tags...


[edited by - rypyr on May 1, 2003 1:27:50 PM]
And please don''t use "friend" unless you really need to.

Properly expose the data that each class needs in a public method and use those...

Regards,
Jeff
no

time to reply later

This topic is closed to new replies.

Advertisement