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

The Partridge Family were neither partridges nor a family. Discuss.
Trainraider
Posts: 3
Joined: October 3rd, 2017, 3:32 am

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

Post by Trainraider » October 13th, 2017, 2:07 pm

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

User avatar
Yumtard
Posts: 575
Joined: January 19th, 2017, 10:28 pm
Location: Idiot from northern Europe

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

Post by Yumtard » October 13th, 2017, 2:29 pm

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

Trainraider
Posts: 3
Joined: October 3rd, 2017, 3:32 am

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

Post by Trainraider » October 13th, 2017, 2:41 pm

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?

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

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

Post by albinopapa » October 13th, 2017, 2:51 pm

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.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

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

Post by albinopapa » October 13th, 2017, 2:53 pm

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.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

User avatar
Yumtard
Posts: 575
Joined: January 19th, 2017, 10:28 pm
Location: Idiot from northern Europe

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

Post by Yumtard » October 13th, 2017, 2:54 pm

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."

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

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

Post by albinopapa » October 13th, 2017, 3:00 pm

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.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

User avatar
Yumtard
Posts: 575
Joined: January 19th, 2017, 10:28 pm
Location: Idiot from northern Europe

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

Post by Yumtard » October 13th, 2017, 3:07 pm

^ 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

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

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

Post by albinopapa » October 13th, 2017, 3:23 pm

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.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

Trainraider
Posts: 3
Joined: October 3rd, 2017, 3:32 am

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

Post by Trainraider » October 13th, 2017, 9:57 pm

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.

Post Reply