Jump to content
  • Advertisement
Sign in to follow this  
KyleM

Help on passing pointers

This topic is 3051 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I decided to make a little text - based horse racing simulator. I have run into some trouble. The horses and thier property's come from a struct called horse, each horse is declared and their property's are changed in the same .cpp file. Another file needs to acsess these structs. I tried making a pointer to each struct. but i dont really have a way in my head on how to pass them menu.cpp - This is the file that needs the struct.
#include "stdafx.h"
#include <iostream>
#include "windows.h"
#include "horses.h"

using namespace std;

//Call and draw the menu
void displayMenu()
{
	cout<<"\nYou walk up to the betting stands, the horse's statistics are\ndisplayed on a screen"<<endl;
	
}






//Text Functions
void clear_screen()
{
	system("cls");
}

void stall_program(int milleseconds_to_stall)
{
	Sleep(milleseconds_to_stall);
}

void call_horse_stats()
{
	cout<<"\nCharlie - Wins: ";
}


horses.cpp
#include "stdafx.h"
#include <string>
#include <iostream>

using namespace std;

     
  struct horse
	{
		string name;
		int wins;
		int losses;
		double percentChanceOfWining;

	};




//the function used to calculate the horses chances
	double calculate_horses_chances(int wins,int losses)
{

	double horsesChance = (wins / losses) * 100;

	return horsesChance;
}



//initiliaze the horses stats
void init_horses()
{
	
//initliaze the horses
horse charlie;
horse cooldude;
horse shiningFury;
horse burningSoap;
horse smellyPages;

//Set the horses names
charlie.name = "Charlie";
cooldude.name = "Cool Dude";
shiningFury.name = "Shining Fury";
burningSoap.name = "Burning Soap";
smellyPages.name = "Smelly Pages";

//set each horse's wins/losses to a number beetween  1 and 5
//to make it seem like the horse's have raced before and dont have 0 percent odds 

charlie.wins = rand() % 5 + 1;
charlie.losses = rand() % 5 + 1;

cooldude.wins = rand() % 5 + 1;
cooldude.losses = rand() % 5 + 1;

shiningFury.wins = rand() % 5 + 1;
shiningFury.losses = rand() % 5 + 1;

burningSoap.wins = rand() % 5 + 1;
burningSoap.losses = rand() % 5 + 1;

smellyPages.wins = rand() % 5 + 1;
smellyPages.losses = rand() % 5 + 1;


//set up their percent chance of winning
charlie.percentChanceOfWining = calculate_horses_chances(charlie.wins, charlie.losses);
cooldude.percentChanceOfWining = calculate_horses_chances(cooldude.wins, cooldude.losses);
shiningFury.percentChanceOfWining = calculate_horses_chances(shiningFury.wins, shiningFury.losses);
burningSoap.percentChanceOfWining = calculate_horses_chances(burningSoap.wins, burningSoap.losses);
smellyPages.percentChanceOfWining = calculate_horses_chances(smellyPages.wins, smellyPages.losses);


//Set up pointers to the horses
horse * pntrCharlie = &charlie;
horse * pntrCoolDude = &cooldude;
horse * pntrShiningFury = &shiningFury;
horse * pntrSmellyPages = &smellyPages;
}


Any help would be greatly appreciated. :)

Share this post


Link to post
Share on other sites
Advertisement
One suggestion would be to declare the horses outside of your initialization function. This way you can access them in other places.


//.h
horse charlie;
horse cooldude;
horse shiningFury;
horse burningSoap;
horse smellyPages;

//.cpp
init_horses()
{
...
}


Share this post


Link to post
Share on other sites
Quote:
Original post by KyleM
I decided to make a little text - based horse racing simulator. I have run into some trouble. The horses and thier property's come from a struct called horse, each horse is declared and their property's are changed in the same .cpp file. Another file needs to acsess these structs. I tried making a pointer to each struct. but i dont really have a way in my head on how to pass them

menu.cpp - This is the file that needs the struct.
*** Source Snippet Removed ***





horses.cpp
*** Source Snippet Removed ***


Any help would be greatly appreciated. :)


This would be a messy solution but you could try doing this:


#include "stdafx.h"
#include <iostream>
#include "windows.h"
#include "horses.h"

extern horse * pntrCharlie;
extern horse * pntrCoolDude;
extern horse * pntrShiningFury;
extern horse * pntrSmellyPages;


using namespace std;

//Call and draw the menu
void displayMenu()
{
cout<<"\nYou walk up to the betting stands, the horse's statistics are\ndisplayed on a screen"<<endl;

}


//Text Functions
void clear_screen()
{
system("cls");
}

void stall_program(int milleseconds_to_stall)
{
Sleep(milleseconds_to_stall);
}

void call_horse_stats()
{
cout<<"\nCharlie - Wins: ";
}





#include "stdafx.h"
#include <string>
#include <iostream>

using namespace std;


struct horse
{
string name;
int wins;
int losses;
double percentChanceOfWining;

};


//Set up pointers to the horses
horse * pntrCharlie = NULL;
horse * pntrCoolDude = NULL;
horse * pntrShiningFury = NULL;
horse * pntrSmellyPages = NULL;


//the function used to calculate the horses chances
double calculate_horses_chances(int wins,int losses)
{

double horsesChance = (wins / losses) * 100;

return horsesChance;
}



//initiliaze the horses stats
void init_horses()
{

//initliaze the horses
horse charlie;
horse cooldude;
horse shiningFury;
horse burningSoap;
horse smellyPages;

//Set the horses names
charlie.name = "Charlie";
cooldude.name = "Cool Dude";
shiningFury.name = "Shining Fury";
burningSoap.name = "Burning Soap";
smellyPages.name = "Smelly Pages";

//set each horse's wins/losses to a number beetween 1 and 5
//to make it seem like the horse's have raced before and dont have 0 percent odds

charlie.wins = rand() % 5 + 1;
charlie.losses = rand() % 5 + 1;

cooldude.wins = rand() % 5 + 1;
cooldude.losses = rand() % 5 + 1;

shiningFury.wins = rand() % 5 + 1;
shiningFury.losses = rand() % 5 + 1;

burningSoap.wins = rand() % 5 + 1;
burningSoap.losses = rand() % 5 + 1;

smellyPages.wins = rand() % 5 + 1;
smellyPages.losses = rand() % 5 + 1;


//set up their percent chance of winning
charlie.percentChanceOfWining = calculate_horses_chances(charlie.wins, charlie.losses);
cooldude.percentChanceOfWining = calculate_horses_chances(cooldude.wins, cooldude.losses);
shiningFury.percentChanceOfWining = calculate_horses_chances(shiningFury.wins, shiningFury.losses);
burningSoap.percentChanceOfWining = calculate_horses_chances(burningSoap.wins, burningSoap.losses);
smellyPages.percentChanceOfWining = calculate_horses_chances(smellyPages.wins, smellyPages.losses);


//Set up pointers to the horses
pntrCharlie = &charlie;
pntrCoolDude = &cooldude;
pntrShiningFury = &shiningFury;
pntrSmellyPages = &smellyPages;
}

Share this post


Link to post
Share on other sites
Pass the horses to the displayMenu function. You will need a container of some sort. An array is a primitive container.

You will need to move types and functions that are required in multiple files into a header file.

For example, horse.hpp

#ifndef HORSE_HPP
#define HORSE_HPP

#include <string>

struct Horse
{
string name;
int wins;
int losses;
double percentChanceOfWining;
};

const int MaxHorses = 5;

struct Race
{
Horse horses[MaxHorses];
};

void printHorseInfo(Horse horse);

#endif



And menu.cpp

#include "stdafx.h"
#include <iostream>
#include "windows.h"
#include "horses.h"

using namespace std;

//Call and draw the menu
void displayMenu(Race race)
{
cout << "\nYou walk up to the betting stands, the horse's statistics are\ndisplayed on a screen" << endl;

for(int i = 0 ; i < MaxHorses ; ++i)
{
printHorseStatistics(race.horses);
}
}



Then your "init_horses" could return a Race, which in turn returns the horses

// initiliaze the horses stats
Race init_horses()
{
// initliaze the horses
horse charlie;
horse cooldude;
horse shiningFury;
horse burningSoap;
horse smellyPages;

//Set the horses names
charlie.name = "Charlie";
cooldude.name = "Cool Dude";
shiningFury.name = "Shining Fury";
burningSoap.name = "Burning Soap";
smellyPages.name = "Smelly Pages";

//set each horse's wins/losses to a number beetween 1 and 5
//to make it seem like the horse's have raced before and dont have 0 percent odds

charlie.wins = rand() % 5 + 1;
charlie.losses = rand() % 5 + 1;

cooldude.wins = rand() % 5 + 1;
cooldude.losses = rand() % 5 + 1;

shiningFury.wins = rand() % 5 + 1;
shiningFury.losses = rand() % 5 + 1;

burningSoap.wins = rand() % 5 + 1;
burningSoap.losses = rand() % 5 + 1;

smellyPages.wins = rand() % 5 + 1;
smellyPages.losses = rand() % 5 + 1;


//set up their percent chance of winning
charlie.percentChanceOfWining = calculate_horses_chances(charlie.wins, charlie.losses);
cooldude.percentChanceOfWining = calculate_horses_chances(cooldude.wins, cooldude.losses);
shiningFury.percentChanceOfWining = calculate_horses_chances(shiningFury.wins, shiningFury.losses);
burningSoap.percentChanceOfWining = calculate_horses_chances(burningSoap.wins, burningSoap.losses);
smellyPages.percentChanceOfWining = calculate_horses_chances(smellyPages.wins, smellyPages.losses);

Race race = { charlie, cooldude, shiningFury, burningSoap, smellyPages };
return race;
}


Any function that needs access to the horses can be passed the race instance, or just a single horse if that is all that is required. This is a simple example, leaving aside dynamic containers and pass by reference.

One final thing, the following calculation probably won't work for you:

(wins / losses) * 100;

C++ will use integer division unless one of the types is a float or double. This means that the result is the same as division with the remainder discarded. You can change the types of the variables involved, use a cast or simply rearrange the code such that the constant 100.0 is used as the center of the operation:

(wins * 100.0 / losses);

Now the integers are "upgraded" or "promoted" to doubles and you won't have the same problem of the remainder being discarded.

You probably should include a special check in the case losses is 0.

Share this post


Link to post
Share on other sites
Thanks for the help people. Is passing by pointer not a mroe efficent way to do this, im trying to learn and i was just wondering if it's what i should use here. As for the program im going to try rip-off's way. Thanks guys :)

Share this post


Link to post
Share on other sites
I am uncertain if you are declaring memory on the heap or not. If you are, take caution when passing pointers around in the code that carry addresses to the heap. Generally, the function that created that pointer should be the same function that deletes the pointer.

Share this post


Link to post
Share on other sites
Your computer can easily handle copying the couple of bytes that make up a Horse or a Race.

However, as I alluded to in my post, passing by reference is idiomatic in C++. Passing by const reference is safe, it incurs no unnecessary copies and also protects the data by marking it as "const", which prevents it being accidentally modified in the function.

For example, a small change like this to printHorseInfo():

void printHorseInfo(const Horse &horse);

This change needs to be made to both the declaration and definition. Note that the function body does not need to change.

Likewise, displayMenu could be:

void displayMenu(const Race &race)

References are usually a better choice than raw pointers in modern C++. Pointers are generally only used in a handful of situations, and most of these can be wrapped safely. One example is where a "null" value makes sense. It wouldn't make sense to print a null horse, so printHorseInfo() shouldn't take a pointer. But sometimes optional types make sense. For example, a homing rocket launcher might have a target. But if there is nothing to target at the moment then the rocket's target might be set to "null" to indicate this. However, we could use boost::optional to indicate this.

Dynamic allocation and polymorphism are two more cases where pointers might be used. But in modern C++ we would use smart pointers or containers, such as std::shared_ptr<> or std::vector<> to handle such cases.

Share this post


Link to post
Share on other sites
In addition to the use of vectors, they manage object memory for you, however, you must remember to clear the vector before it goes out of scope.

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
std::vector does not require you to clear it, it is a RAII type.


Is this true even if the vector holds pointers? Does the vector automatically call the destructors?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!