c++ constructor question

Started by
8 comments, last by Boku San 18 years, 4 months ago
Say I have a "Ragdoll" class that is composed by 10 "balls"

class Ragdoll
{
Ball balls[10];
};
And the Ball class contains a pointer to the owner ragdoll:

class Ball
{
...
Ragdoll* owner;
};
I want the ball class to have a constructor which takes as parameter the pointer to the Ragdoll which owns it: something like

Ball::Ball(Ragdoll* ownerin)
{
owner=ownerin;
}
The problem is I dont know how to call the Ball::Ball constructor when I make a ragdoll! Say I call

Ragdoll ragdolls[2]
I dont know where-how to specify the argument for the Ball constructor!
Got a Mac? Check out my game at [a]http://www.radicalrebound.com[/a]
Advertisement
You cannot pass arguments to the constructors for objects in static arrays. Only the default constructor can be invoked. To get around this limitation, you might consider using std::vector instead of an array, or having a Ball member function which sets the owner after construction. Yucky, I know. Yet another ugliness of C++.
Using static arrays, the constructors of all 10 balls are automatically called. In the ragdoll constructor, pass the ragdoll pointer to all balls.

I SERIOUSLY need to point out that circular dependencies such as this are very bad practice. I often refer people to this document in cases like this one. It's a bit lengthy but well worth the time.
Quit screwin' around! - Brock Samson
Hmm, so I get it I cant do it "automatically".

>I SERIOUSLY need to point out that circular dependencies such as this are very bad practice

Bah, are you sure? It looks quite natural to me.
Got a Mac? Check out my game at [a]http://www.radicalrebound.com[/a]
Quote:Original post by The Najdorf
>I SERIOUSLY need to point out that circular dependencies such as this are very bad practice

Bah, are you sure? It looks quite natural to me.

Take it from someone who has done it. The more a class is relied upon by other classes, the harder it becomes to modify. Two classes relying on eachother can cause implementation to become very sluggish later on down the road. If you're trying to do what I think you're doing (ragdoll animation or physics), you'll be in dependency hell later on. I did this in a physics engine I wrote a long time ago.

Just read the first couple of pages of the link I sent you. It'll hit the nail on the head... and probably make you want to keep reading. =)
Quit screwin' around! - Brock Samson
class Ragdoll;class Ball{public:	Ball() : parent(0)	{	}	Ball(Ragdoll* parents) : parent(parents)	{	}private:	Ragdoll* parent;};class Ragdoll{public:	Ragdoll()	{		for(int count=0;count<10;count++)		{			balls[count] = new Ball(this);		}	}private:	Ball* balls[10];};
We should do this the Microsoft way: "WAHOOOO!!! IT COMPILES! SHIP IT!"
He's well aware that it's possible, dbzprogrammer -- but then so is no-function, no-loop goto spagetti.

Making your dependancy graph have no cycles is a very good goal.

So why do balls need to know their parent?
Quote:Original post by coderx75
Quote:Original post by The Najdorf
>I SERIOUSLY need to point out that circular dependencies such as this are very bad practice

Bah, are you sure? It looks quite natural to me.

Take it from someone who has done it. The more a class is relied upon by other classes, the harder it becomes to modify. Two classes relying on eachother can cause implementation to become very sluggish later on down the road. If you're trying to do what I think you're doing (ragdoll animation or physics), you'll be in dependency hell later on. I did this in a physics engine I wrote a long time ago.

Theres nothing inherantly wrong about two classes being tightly coupled like this, as long as they act as a single unit with a well defined interface. Problems creep in when you've got a two classes depending on each other, and each of those is depending on each other, etc. etc.

You can't expect to be able to rip out *any* class and reuse it elsewhere. Often you want to be able to reuse complete modules (which may or may not be class sized).
Quote:Original post by OrangyTang
You can't expect to be able to rip out *any* class and reuse it elsewhere. Often you want to be able to reuse complete modules (which may or may not be class sized).


Certainly. If everything was fully independant, everything would be a monster. ( Despite my CS prof that thinks that's what encapsulation means )

I just mean that you should, ideally, have it so that you can draw the graph of all your components with all the "needs to know about" arrows going the same (general) way -- it's the same sort of idea as why forward gotos are alright but backwards ones are evil.
Quote:Original post by me22
... ( Despite my CS prof that thinks that's what encapsulation means )


Try telling him this:
Quote:From "Encapsulation vs. Inheritance"
One of the primary advantages of using objects is that the object need not reveal all of its attributes and behaviors. In good O-O design (at least what is generally accepted as good), an object should only reveal the interfaces needed to interact with it. Details not pertinent to the use of the object should be hidden from other objects. This is called encapsulation.


Encapsulation isn't "keeping everything in separate modules" -- I'd call that "modular design", or something similar. Encapsulation is "exposing the controls, but never the internals."

If anyone wants to argue that/would like to correct me, I say feel free.

To the OP:
Why do Balls need to know about owners? Why not just Ragdoll::ball? Typing it out I can almost understand why, but none of the reasons my mind formulate equate to "good practice".

Considered refactoring? I hear Washu's journal has some good information once in a while that might help... (/winks at Washu)
Things change.

This topic is closed to new replies.

Advertisement