Page 1 of 2

Compiler doesn't like it when I pass objects by reference

Posted: October 13th, 2017, 2:07 pm
by Trainraider
So I've gone up through tutorial 15 in Chili's Beginner C++ series and I figured I'd make pong. I've got most of the mechanics working, except now when I try to pass objects by reference through a function, the compiler freaks out. It says I need a comma before the "&" and that the function doesn't take 2 arguments when it does take 2 arguments. Here's an example function that shit the bed.

Code: Select all

//Ball.h
void Collision( Paddle& paddle, bool leftSideOfScreen);

Code: Select all

//Ball.cpp
void Ball::Collision(Paddle& paddle, bool leftSideOfScreen)
{
	if (leftSideOfScreen)
		x = paddle.GetCoord().x + paddle.width;
	else
		x = paddle.GetCoord().x - dimension;
	hSpeed = -1 * (hSpeed + 1);
}
I've checked and double checked that I passed the objects exactly the same as Chili did with the gfx and dude objects from previous tutorials and I can't find any reason this is happening.

Oh and I put the whole project on Github so you can look at it more. https://github.com/Trainraider/Pong

Re: Compiler doesn't like it when I pass objects by referenc

Posted: October 13th, 2017, 2:29 pm
by Yumtard
You have circular dependance (Ball includes Paddle and Paddle includes ball)

One work around is to use forward declaration. You can do it like this.

Code: Select all

#pragma once
#include "Graphics.h"
#include "Coord.h"
#include <random>

class Paddle;

class Ball
{
public:
	Ball(Graphics& gfx);
	Coord GetCoord() const;
	void Move();
	void Draw();
	void Collision( Paddle& paddle, bool leftSideOfScreen);
Most of the times the best thing is to try and avoid circular dependance tho

Re: Compiler doesn't like it when I pass objects by referenc

Posted: October 13th, 2017, 2:41 pm
by Trainraider
Thanks! That just fixed everything. So I generally need to avoid 2 objects referencing each other? Would a more correct way to go about this be to have the game object handle all the interaction between the ball and paddles with ball and paddles not knowing the other exists?

Re: Compiler doesn't like it when I pass objects by referenc

Posted: October 13th, 2017, 2:51 pm
by albinopapa
You could use the Game class or add a collision class that knows about Ball and Paddle. Game would know about the Collision class and the Collision class would know about Ball and Paddle. Ball and Paddle wouldn't know about the Collision class nor each other.

Re: Compiler doesn't like it when I pass objects by referenc

Posted: October 13th, 2017, 2:53 pm
by albinopapa
That does lead to needing accessors like GetPosition() and SetPosition( newPos ) since you'd be using an outside class, but it can't be helped sometimes.

Re: Compiler doesn't like it when I pass objects by referenc

Posted: October 13th, 2017, 2:54 pm
by Yumtard
Yeah,

what happens wit circular dependency is the compiler goes through ball.h
when it gets to #include "paddle.h" it will go into paddle.h to see what's in there. Then inside Paddle.h it will get to #include "Ball.h" and it will go inside Ball.h and get to #include "paddle.h" and...... you see the point :D

When you do forward declaration like class Paddle; you're basically just promising the compiler that a class Paddle exists.

from wikipedia

"Circular dependencies can cause many unwanted effects in software programs. Most problematic from a software design point of view is the tight coupling of the mutually dependent modules which reduces or makes impossible the separate re-use of a single module.

Circular dependencies can cause a domino effect when a small local change in one module spreads into other modules and has unwanted global effects (program errors, compile errors). Circular dependencies can also result in infinite recursions or other unexpected failures.

Circular dependencies may also cause memory leaks by preventing certain very primitive automatic garbage collectors (those that use reference counting) from deallocating unused objects."

Re: Compiler doesn't like it when I pass objects by referenc

Posted: October 13th, 2017, 3:00 pm
by albinopapa
One thing Yumtard isn't mentioning is forward declaring a class isn't the only step needed. The compiler still needs to know about the class that is being forward declared and used and there are times you can't simply forward declare a class to get out of circular dependencies.

Once you forward declare a class in the header, you still need to #include it in your .cpp file.
Template classes like std::vector or std::unique_ptr need to know the full implementation of the class during compile time, so if class A needs a vector of class B, you cannot forward declare class B.

Re: Compiler doesn't like it when I pass objects by referenc

Posted: October 13th, 2017, 3:07 pm
by Yumtard
^ Good point. In this case you had already included Paddle.h in your cpp file. If you don't, the compiler will trust you that there's a class called Paddle, but it still wont know anything about its functions

Re: Compiler doesn't like it when I pass objects by referenc

Posted: October 13th, 2017, 3:23 pm
by albinopapa
Just looking through your repo and found something interesting:

Code: Select all

gfx.PutRect(x, y, dimension, dimension, 0xFFFFFF);
The chili framework has some Color constants that you can use instead of having to type in hexadecimal values.

Code: Select all

// For instance
gfx.PutRect(x, y, dimension, dimension, Colors::White);
Also, he has a color class that you can use for colors that aren't listed allowing you to create colors using the individual color channels.

Code: Select all

gfx.PutRect(x, y, dimension, dimension, Color( 128, 0, 128 ) );
Of course, you can still use the hex value as the Color class does have a constuctor for unsigned int as well.

Re: Compiler doesn't like it when I pass objects by referenc

Posted: October 13th, 2017, 9:57 pm
by Trainraider
albinopapa I actually knew about those but I just find hexadecimal the most convenient. I've worked with hex before and it's easier for me to use off the top of my head rather than looking up Chili's color stuff.

Anyway thank you guys for all the info it was a huge help! I'm really enjoying the speed and freedom of C++ over the bullshit that is Game Maker Studio so far.