Er, okay.
I have two classes: A and B.
Class B must container a member which is a class A object. Class A must contain a member that's a class B object.
How do I declare these so that I don't get errors?
Er, okay.
I have two classes: A and B.
Class B must container a member which is a class A object. Class A must contain a member that's a class B object.
How do I declare these so that I don't get errors?
I'll give you some hints:
forward declarations
OR
change where the #include statements are placed
Eh, what's a forward declartion? Is that just a class name; thing? I tried doing that and i think I got an error, but...
Show us what you did. Also, think about the logic behind having a circular dependence like that, and what it means (hint: it comes out bad). Use a pointer or reference to one (or both) of the objects if possible, instead of actual instances.
The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.
Zack L. could you give an example of doing this? TIA
As Zach pointed out, this leads to infinite dependence, or whatever you call it.
Class A's constructor constructs an object of class B. But class B's constructor constructs an object of class A. Therefore, you'll get an infinite number of objects of class A and B being constructed.
>>could you give an example of doing this?
Very simply, instead of:
You can have it hold pointers to each other:Code:class B; //forward declaration class A { public: //... protected: B member; //holds a B, which... }; class B { public: //... protected: A member; //holds an A, which... (see above) };
That's an example of one thing you can do, though without further information I have no idea exactly what the original poster's intention was in having each contain an object of the other.Code:class B; //forward declaration class A { public: A() :member(this) {} //Pass a pointer to myself when constructing B protected: B member; //Holds a B, which... }; class B { public: B(A* parent) :member_parent(parent) {} protected: A* member_parent; //Holds a pointer to the A that it belongs to };
Just Google It. √
(\ /)
( . .)
c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.
Once I have multiple objects created, I need to be pick and object and then grab a specific material for it. Lets say I grab the steelBall and need to get the info from the mat class for the steel material or glassCup and need to grab the glass material from the mat class. The way i am trying to do this is in the obj class have a variable, matID, and compare it to the matID in the mat class. Hope i explained this well enough.
Code:#include <math.h> #include <vector> #include <iostream> #include <string> using namespace std; const double gravity = 9.8; //Object Class class obj { public: string objName; double matID; double objMass; bool objRoll; }; class mat { public: double matID; double objWeight; double objDensity; } int main() { obj steelBall, glassCup; mat steel, glass; steelBall.matID = 0; steelBall.mass = 5; steel.matID = 0; steel.weight = 3; steel.density = 5; glassCup.matID = 1; glassCup.mass = 3; glass.matID = 1; glass.weight = 2; glass.density = 2; return 0; }//end main()
Better yet, you can use pointers:
That saves you the trouble of trying to match up ID's every time you want to calculate something using information from the material.Code:class mat; //forward declaration class obj { public: string objName; mat* material; double objMass; bool objRoll; }; ... obj steelBall, glassCup; mat steel, glass; steelBall.material = &steel; //material now points to steel steelBall.mass = 5; steel.matID = 0; steel.weight = 3; steel.density = 5; ... std::cout << "The density of the Steel Ball is " << steelBall.material->density << "." << std::endl;
Just Google It. √
(\ /)
( . .)
c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.
Thank you so much for the help. Hope this helps the person who orginally started this post.
In Hunter2's example, a reference would work as well (this is a personal preference, but in this case, it is the solution that I would prefer).
In either case (pointer or reference), you have to make sure that your material object does not go out of scope at any point. (If you just used an object, it would simply be copied -- make sure appropriate copy ctor and operator= is defined.)
One type of solution would be to make a singleton class, a 'MaterialRegistry'. Essentially, it would allow you to construct a material object, and key it to, say, a specific name. Then, if you want steel, you ask the registry object for the material data for 'steel', and if it has the data, it gives it to you. If it didn't, you could deal with it as you saw fit.
What this solution allows you to do is to avoid replicating data for a specific material, which avoids the necessity of hard-coding (or even reading in) data in multiple places throughout your code.
Here is a reference I found on design patterns: http://home.earthlink.net/~huston2/dp/patterns.html
I haven't thoroughly checked over the site, but it looks fairly decent. They have the singleton pattern on there, and looking at the other 'Creational Patterns' probably give you a decent idea about where I was headed with the idea of a registry.
Anyway, if you are interested in OO design like this, I also recommend the Design Patterns book.
The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.
Hm. I'm going to assume that the constructor does something important, because just having something like A *member_parent gives me a "syntax error before *" message. What exactly IS the :member syntax after the function prototype anyway? I've never seen that before. What does it do?Code:class B { public: B(A* parent) :member_parent(parent) {} protected: A* member_parent; //Holds a pointer to the A that it belongs to };
You need a forward declaration of A:
Code:class A; class B { public: B(A* parent) :member_parent(parent) {} protected: A* member_parent; //Holds a pointer to the A that it belongs to };
The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.
>>What exactly IS the :member syntax after the function prototype anyway?
When a class contains member variables, and an instance of the class is created (an object of the class), all of its member variables must also be created - and if one of the member variables is an object of another class, it must be constructed. :member(something) simply tells the constructor that when constructing 'member', you should pass (something) to its constructor. So:
B(A* parent) :member_parent(parent) {}
The constructor of B takes an A*, and we'll name it 'parent'. Now, when B's constructor is called, i.e. it's being constructed, it will construct member_parent which is an A* by passing the A* constructor 'parent'. Since a pointer is a POD type, the 'constructor' of A* is automatically created, and all it does is copy the value passed to it into itself. So what happens is the value stored in 'parent' is copied into member_parent when B's constructor is called.
Another example:
So in A's constructor, bObject is constructed by passing the values 5 and 6 to its constructor, and bObject2 is constructed by passing the values 1 and 2 to its constructor.Code:class B { public: B(int arg1, int arg2) { x = arg1; y = arg2; } protected: int x; int y; }; class A { public: A() :bObject(5, 6), bObject2(1, 2) { } protected: B bObject; B bObject2; };
Last edited by Hunter2; 01-30-2005 at 02:04 PM.
Just Google It. √
(\ /)
( . .)
c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.
Dev-C++ isn't letting me do forward declarations. Do I need to put them somewhere special?
Well, what errors are you getting? And what's your code?
Just Google It. √
(\ /)
( . .)
c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.