Trouble with passing class objects by reference

Hi, I am working on a program to simulate a zoo, essentially there are passengers that are waiting for a ride in cars around the zoo. This is a multi-threaded program using the std::thread class, and essentially I pass an array of passengers and an array of cars into a function as a thread is initialized, then based on some the values of the objects, I place cars and passengers each into a std::queue. Then each passenger is paired with a car until one of the queues is empty. There is much more to the program than this, but I think this is enough to show the problem I am having.

The problem is that when I modify the member variables of the "front" member of each queue, the values don't stick when I access the values directly. You can see in the code below that I try to print the value

Here is the header of the function that the next code snippets are from.
void carsManage(int time, car cars[], gasStation& station, visitor visitors[], int numVisitors, int numPumps, int numCars, int rideTime)

here you can see the queues are initialized and filled with certain objects
1
2
queue<visitor> rideQueue;
	queue<car> carQueue;


1
2
3
4
5
6
7
8
9
10
11
for (int i = 0; i < numVisitors; i++)//checking for visitors that need rides
	{
		if (!visitors[i].getRidden())
			rideQueue.push(visitors[i]);
	}

	for (int i = 0; i < numCars; i++)//adding all ready cars to queue
	{
		if (cars[i].getReady())
			carQueue.push(cars[i]);
	}


In the code below there are two std::cout statements that should return the same values for each object, but they do not.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
while (rideQueue.size() > 0 && carQueue.size() > 0)//putting drivers in cars until one runs out
	{
		rideQueue.front().setRidden(true);
		rideQueue.pop();
		carQueue.front().setRides(carQueue.front().getRides() - 1);
		carQueue.front().setReady(false);
		carQueue.front().setLeaveTime(time);
		cout << carQueue.front().getLeaveTime() << "\n";
		carQueue.pop();
	}
	int carsOut = 0;
	
	for (int i = 0; i < numCars; i++)//calculating cars out driving
	{
		cout << cars[i].getLeaveTime() << "\n";
		if (cars[i].getLeaveTime() <= time && cars[i].getLeaveTime() > 0)
			carsOut += 1;
	}


also, here is the thread initialization, if that helps clarify anything

thread carAgent(carsManage, time, cars, ref(station), visitors, numVisitors, numPumps, numCars, rideTime);

If anything needs to be clarified, let me know; Any help would be greatly appreciated.
Last edited on
Alright after doing a lot of debugging I narrowed it down to the queue class. Apparently, modifying the front element of the queue class isn't done by reference, so idk what to do about that.
Is there a way to push an object into a queue by reference?
std::queue::front returns by reference.

I'm not really sure what your code does, but this looks highly suspicious to me:
3
4
5
6
7
8
9
		rideQueue.front().setRidden(true);
		rideQueue.pop();
		carQueue.front().setRides(carQueue.front().getRides() - 1);
		carQueue.front().setReady(false);
		carQueue.front().setLeaveTime(time);
		cout << carQueue.front().getLeaveTime() << "\n";
		carQueue.pop();
Why set all that information and then destroy it? Do you understand what pop() does?
Last edited on
Well this particular thread is generated many times in the loop, so the queue itself is populated and depopulated with every iteration. That's not the problem though. And yeah I know front returns the reference, but the problem I am having is that push does not actually pass by reference, rather by value. If you know a way to fix this, that would be awesome, but either way thank you for the response.
tmorlan wrote:
Is there a way to push an object into a queue by reference?
Maybe you want to use emplace?

http://www.cplusplus.com/reference/queue/queue/emplace/

I'm not sure why you are asking for what you are asking for. If an object is not in a container, there's no way to ever make that object be in that container. You would work around this by using e.g. smart pointers wrapper classes such as std::unique_ptr so that the object is persistent but the wrapper class that holds it can be juggled around, but you may want to reconsider your design.
I think the problem is that you want to store a reference to an existing object in your containers, and you can't do that directly. Consider storing a std::reference_wrapper or a pointer to the object instead.

http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper

Thanks for the responses guys. cire, you were right, that was the issue and making the queue of objects a queue of object pointers solved it. I know my design is sh*t, and I wish I could redesign it, but I'm just a lowly college student, and this is a project that was due yesterday. Thanks again!
Topic archived. No new replies allowed.