How to call multiple classes in C++ - c++

Here is the code I'm trying to create, and yes its messy for now. To give some back story I'm trying to figure out how to call a class multiple times without doing it seperately. What I mean is instead of performing:
Dice diceOne;
Dice diceTwo; and so on, I want to know if it is possible to just put it as Dice dicewhatever(*) and have that be a modifiable variable. This is so that I can set that variable to a number and then decrement it based on a score.
I dont know if this is even possible, but at this point I've beat my head against this so much I'm just pulling at straws to see if it would be a fit.
class Dice {
public:
Dice();
int Roll();
int currentDiceSide();
private:
int diceRoll;
int diceReRoll; //Declares and initializes the number of dice to allow for roll next dice throw.
};
Dice::Dice()
: //This is the beginning of the class and sets diceRoll to zero
diceRoll(0)
{
}
int Dice::Roll()
{ //This function actually does the random roll within the class Dice.
diceRoll = ((rand() % 6) + 1);
return diceRoll;
}
int Dice::currentDiceSide()
{ //This function returns the value of the dice roll for the class call.
return diceRoll;
}
void Game::Rules()
{
ifstream inFile;
inFile.open("Farkle Rules.txt");
string line;
if (inFile.fail()) {
cerr << "Error opening file" << endl;
exit(1);
}
if (inFile.is_open()) {
while (inFile.good()) {
getline(inFile, line);
cout << line << endl;
}
inFile.close();
}
}
void Game::GetPlayerInput(int playerInput)
{
cin >> playerInput;
}
void Game::RunGame()
{
Rules();
bool farkle = false;
double turnSum = 0;
double value = 0;
int i = 0;
int w = 6;
int players = 0;
int numPlayer = 0;
int diceOneValue = 0;
int diceTwoValue = 0;
int diceThreeValue = 0;
int diceFourValue = 0;
int diceFiveValue = 0;
int diceSixValue = 0;
int num1s = 0; //Declaring and initializing the variables to hold how many times a number shows up in a roll.
int num2s = 0;
int num3s = 0;
int num4s = 0;
int num5s = 0;
int num6s = 0; //
srand(static_cast<unsigned int>(time(0)));
cout << "Welcome to Farkle!" << endl
<< endl;
cout << "Please enter the number of players " << endl;
cin >> players;
//Dice diceOne;
//diceOne.currentDiceSide();
//Dice diceTwo;
//diceTwo.currentDiceSide();
//Dice diceThree;
//diceThree.currentDiceSide();
//Dice diceFour;
//diceFour.currentDiceSide();
//Dice diceFive;
//diceFive.currentDiceSide();
//Dice diceSix;
//diceSix.currentDiceSide();
Dice diceOne(w);
< -this is the line that I would like to create with a variable that is modifiable.

You cannot give each Dice object a name, but you can create a Vector of Dice object pointers (vectors are basically resizable arrays), like this:
#include <vector>
#include <iostream>
//...
std::cout << "Please enter the number of players " << std::endl;
std::cin >> players;
// do something to make sure players is an integer
// initialize the empty playerDice vector
std::vector<Dice*> playerDice = {};
for (unsigned i = 0; i < players; ++i) {
playerDice.push_back(new Dice); // this adds a new Dice object pointer to the end of the vector
playerDice.at(i)->currentDiceSide();
}
You have then called the currentDiceSide() function on each Dice object you created, and have neatly organized them in a Vector, which you can access like this:
// say we want to access the third Dice Object,
// Vectors start counting at 0, so we acces the element at Index 2.
playerDice.at(2)->doSomething();
Now because you instantiated those Dice objects with new you have to remember to delete them when you're finished with them, otherwise this will create a memory leak.
//...
// this deletes all the Dice objects in the vector, and points the remaining pointers to null
for (auto d : playerDice) {
delete d;
d = nullptr;
}
Or, better yet, if you're using C++11, you can use std::unique_ptr instead of the raw C-style pointers. Those will prevent you from creating memory leaks, because they will be deleted when they go out of scope. Note you have to #include <memory> to use these.
The vector definition then turns into:
std::vector< std::unique_ptr<Dice> > playerDice = {};
And the creation of the objects would look like this
for (unsigned i = 0; i < players; ++i) {
Dice* temp = new Dice;
temp->currentDiceSide();
std::unique_ptr<Dice> uPtr{ temp };
playerDice.push_back(std::move(uPtr));
}
You can then just clear the vector when you're done with all the objects:
playerDice.clear();
which will delete all the Dice objects that you put into the vector.

Related

C++ beginner declaring a function involving array of structures

There is a few lines of my code that I would like to define as a function because I plan to use it multiple times. portion of code is as follows:
// loop within loop used to reorder with highest price at the top
for(i=0;i<x;i++){
for(t=i;t<x;t++){
if(f[i].price < f[t].price) {
temp = f[i].price;
f[i].price = f[t].price;
f[t].price = temp;
}
}
}
I hope to be able to enter new values for x and f each time I call the function. I have included all of my code below. If I'm unclear about my objective in anyway please feel free to ask. I apologize in advance for the improper terminology I am new to this. Thank you
#include <iostream>
using namespace std;
struct List
{
char name[10];
int price;
};
int main()
{
//x represents number of structures within array!
int x;
cout << "How many items would you like to list under the fruit menu?\n";
cin >> x;
//array of structures fruit
struct List f[x];
int i;
//input values into structure
for (i = 0; i < x; i++) {
cout << "\nEnter fruit name, and price.\n";
cin >> f[i].name;
cin >> f[i].price;
};
//variables for reordering
int temp;
int t;
// loop within loop used to reorder with highest price at the top
for(i=0;i<x;i++){
for(t=i;t<x;t++){
if(f[i].price < f[t].price) {
temp = f[i].price;
f[i].price = f[t].price;
f[t].price = temp;
}
}
}
//Output of menus
//fruit Menu
cout << "\n\nFruit Menu";
for (i = 0; i < x; i++) {
cout << "\n" << f[i].name << " $" << f[i]. price;
};
return 0;
}
I suppose it is an assignment that says "implement your own sort function for sorting an array of fruits", so I take the data structure "array of fruits" as given. You can, of course, change this to vector<struct Fruit> as well, but that's a different topic.
Maybe the following fragments help you finishing your code. It contains functions for entering, sorting, and printing the array with some samples how to deal with the parameters and the calls. You'll have to finalise the code.
Have fun!
#include <iostream>
using namespace std;
struct Fruit
{
char name[10];
int price;
};
// enter up to nrOfFruis; return number of fruits actually entered
int enterFruits(struct Fruit *fruits, int maxNrOfFruits) {
int entered = 0;
while (entered < maxNrOfFruits) {
cin >> fruits[entered].name;
entered++;
}
return entered;
}
void sortFruits(struct Fruit* fruits, int nrOfFruits) {
// your sort code goes here
// example for swaping two elements:
Fruit temp = fruits[0];
fruits[0] = fruits[1];
fruits[1] = temp;
}
void printFruits(struct Fruit *fruits, int nrOfFruits) {
cout << "\n\nFruit Menu";
for (int i = 0; i < nrOfFruits; i++) {
cout << "\n" << fruits[i].name << " $" << fruits[i]. price;
};
}
int main()
{
// Your task: put a proper loop and exit condition arround the following lines...
int x;
cout << "How many items would you like to list under the fruit menu?\n";
cin >> x;
struct Fruit fruits[x];
int entered = enterFruits(fruits, x);
sortFruits(fruits, entered);
printFruits(fruits, entered);
return 0;
}
You cannot allocate an array on the stack if you do not know it's size at compile time. Therefore, you need to dynamically allocate memory for it(you also need to remember to delete it):
//x represents number of structures within array!
int x;
cout << "How many items would you like to list under the fruit menu?\n";
cin >> x;
//array of structures fruit
struct List * f = new List[x];
//...
delete [] f;
Alternatively, you could do it the C++ way, using vector, having the vector elements on the stack:
int x;
std::cin>>x;
std::vector<A> v(x);
for( size_t i = 0; i < x; i++)
{
std::cin >> v[i].x;
}
If you just want to pass an array to a function you can do so like this:
void sortArray(struct List list[]);
void sortArray(struct List* list, int n); // n = size of array
may be better to just use std::vector or some other list container instead. :)
Sounds like you want a function that receives an array t and index x, and you want to mutate the array in the function?
C++ is "pass by value", so to mutate the array you have to have your function take a reference (or pointer) to the array so that you're mutating the original array and not a copy of it, so just have your function signature like this: func(T& t, int x) (assuming T is the type of array t).

'fArray' was not declared in this scope

Hello I'm having this issue with my C++ problem I'm working on.
Here is the code
Cell.h
#ifndef CELL_H
#define CELL_H
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
class Cell
{
private:
int level;
int row;
int column;
//declares a variable called ptrFunction_array which is an array of 3 function pointers.
typedef void (*ptrFunction[])(void);
static void function1()
{
cout << "I'm function 1";
}
static void function2()
{
cout << "I'm function 2";
}
static void function3()
{
cout << "I'm function 3";
}
public:
Cell(int currentLevel, int currentRow, int currentColumn)
{
level = currentLevel;
row = currentRow;
column = currentColumn;
ptrFunction = new *fArray[3];
fArray[0] = function1();
fArray[1] = function2();
fArray[2] = function3();
}
virtual ~Cell();
void tick()
{
int randomNumber = rand() % 3;
cout << "Cell(" << level << ", " << row << ", " << column << ") ";
fArray[randomNumber];
}
};
#endif // CELL_H
Main.cpp
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include "Cell.h"
using namespace std;
Cell ****myArray;
int main()
{
int level = 0;
int row = 0;
int column = 0;
char userInput = 'y';
srand (time(NULL));
do
{
cout << "Please input the amount of levels: ";
cin >> level;
cout << "Please input the amount of rows: ";
cin >> row;
cout << "Please input the amount of columns: ";
cin >> column;
cout << endl;
myArray = new Cell *** [level];
// Set random number to the elements of the array
for (int currentLevel = 0; currentLevel < level; currentLevel++)
{
myArray [currentLevel] = new Cell ** [row];
for (int currentRow = 0; currentRow < row; currentRow++)
{
myArray [currentLevel][currentRow] = new Cell * [column];
for (int currentColumn = 0; currentColumn < column; currentColumn++)
{
myArray [currentLevel][currentRow][currentColumn] = new Cell (currentLevel, currentRow, currentColumn);
myArray [currentLevel][currentRow][currentColumn] -> tick();
cout << " ";
}
cout << endl;
}
cout << endl;
}
cout << "Do you want to try again? (y / n) ";
cin >> userInput;
cout << endl;
if ((userInput == 'y') || (userInput == 'Y'))
{
for (int currentLevel = 0; currentLevel < level; currentLevel++)
{
for (int currentRow = 0; currentRow < row; currentRow++)
{
for (int currentColumn = 0; currentColumn < column; currentColumn++)
{
delete[] myArray[currentLevel][currentRow][currentColumn];
}
delete[] myArray[currentLevel][currentRow];
}
delete[] myArray[currentLevel];
}
delete[] myArray;
myArray = NULL;
}
}while (userInput != 'n');
return 0;
}
I notice that my fArray isn't inside the scope. the Line ptrFunction = new *fArray[3]; is where my error is. I've recently started learning C++ so I'm in the process of trying to understand why my typedef void (*ptrFunction[])(void); isn't correctly initializing the fArrayfor my program. The goal of my program is to be able to create a 3 dimensional array and be able to point to the Cell Objects and be able to track the location x,y,z.
Why does an error like this happen?
I'm going to ignore the four star pointer for now and stick to what's giving OP the most immediate grief.
A quick walk-through:
Cell(int currentLevel, int currentRow, int currentColumn)
{
level = currentLevel;
row = currentRow;
column = currentColumn;
Not bad to here. But...
ptrFunction = new *fArray[3];
This says assign to the variable ptrFunction, which must already exist and doesn't, a newly allocated array of 3 fArrays. The problem here is ptrFunction has been defined as a type, not a variable. fArray is not a type.
fArray[0] = function1();
fArray[1] = function2();
fArray[2] = function3();
Use fArray as a variable, making what's gone wrong here somewhat clear.
}
Cell needs to look a bit more like this, but not exactly. More on that later.
Cell(int currentLevel, int currentRow, int currentColumn)
{
level = currentLevel;
row = currentRow;
column = currentColumn;
ptrFunction * fArray = new ptrFunction[3];
Now fArray is a variable that points to one or more objects of type ptrFunction (but the definition of ptrFunction is somewhat broken), and points fArray at three ptrFunctions. Technically it points at the first of three ptrFunctions.
fArray[0] = function1();
fArray[1] = function2();
fArray[2] = function3();
}
Now we have an fArray, but it is a local variable and it only exists between the curly braces of Cell's constructor. When the constructor exists, the pointer goes away. The memory allocated does not and is lost. Without fArray pointing to it, you can't easily find it to use or delete it. fArray needs wider scope so that A) the memory isn't lost, and B) so that tick and other members of Cell can see it.
class Cell
{
private:
ptrFunction * fArray;
int level;
and in the constructor:
Cell(int currentLevel, int currentRow, int currentColumn)
{
level = currentLevel;
row = currentRow;
column = currentColumn;
fArray = new ptrFunction[3];
That fixes the can't find fArray.
My recommendation is to get one Cell working and then take a stab at getting a 1 dimensional array of Cells working. When you have one dimension, then try two. You might find that's all you need.
Edit
Forgot to mention this: Function pointers to members functions are an absolute expletive deleted to get right. Here is a page on common pitfalls and how to avoid them.
And here is how we avoid this smurf in the here and now of Modern C++: std::bind and std::function. The tutorials at the bottom of the linked document pages probably describe how to use them for simple cases better than I can.

Incorrect Variable output with Vector Class C++

My output for the call to the temporary array size wont correctly output. It resizes as according, but I can't get the MAX to display the new value of the new array. My error is within the Resize function within the class.
#include <iostream>
#include <vector>
#include <string>
#include <math.h>
#include <ctime>
using namespace std;
class VectorClass {
private:
int * Vector;//This will be our resizeable array
int Size; //Keep track of vector current size
int MAX=10;
int growth = 5;
int num;
int Resize(int growth, int MAX);
public:
VectorClass(int growth, int Size);
~VectorClass();
int AddItem(int num);
void RemoveItem();
void Print(void);
};
VectorClass::VectorClass(int growth, int Size)
{
Size = 10;
growth = 5;
Vector = new int[Size];
}
VectorClass::~VectorClass()
{
cout << "Destructor was called." << endl;
}
//Will insert num into the vector at the current open position
int VectorClass::AddItem(int num)
{
Vector[Size] = num;
Size++; //Indicate that there isnt as much free space
if (Size == MAX)
{
Resize(Size, MAX);
}
Print();
return num;
}
//Get rid of the most recently added item
void VectorClass::RemoveItem()
{
Size--; //Tricks the vector into one fewer elements in it it currently does
Print();
}
int VectorClass::Resize(int growth, int MAX)
{
cout << "Array is full! Resizing the Array!" << endl;
//Step 1: make a copy
int * temp = new int[MAX]; //Make a new array, same size as exiting array
//loop that copies the original into the copy
for (int i = 0; i<MAX; i++)
{
temp[i] = Vector[i];
}
//Step 2: Delete the original
delete[] Vector; //Deletes all elements in the array Vector from the Heap
//Step 3: Make a bigger vector
Vector = new int[MAX + growth];
//Step 4: Reverse the copy and record the size change
for (int i = 0; i<MAX; i++)
{
Vector[i] = temp[i];
}
MAX = MAX + growth;
//Step 5: Delete the copy
delete[] temp;
cout << "Resize was called.\n" << endl;
return MAX;
}
void VectorClass::Print()
{
cout << "*******************************************************" << endl;
for (int i = 0; i< Size; i++)
{
cout << Vector[i] << endl;
}
cout << "Size = " << Size << "\tMAX = " << MAX << "\t Growth = " << growth << endl << endl;
cout << "*******************************************************" << endl;
}
int main(void)
{
VectorClass V(5,10);
for (int i = 0; i <= 4; i++)
{
int x = rand();
V.AddItem(x);
}
//Print the Vector #1
V.Print();
//Delete 2 Items
V.RemoveItem();
V.RemoveItem();
//Add 9 random Numbers
for (int i = 0; i <= 8; i++)
{
int x = rand();
V.AddItem(x);
}
//Print the Vector
V.Print();
system("pause");
return 0;
}
Several things are wrong with you code. The first one, probably not the one you care about most, is that you never free the memory. You should do it in your destructor, or even better use a std::unique_ptr to handle your memory.
Now, i believe you are yourself confused about your own variables. I see that you possess a variable member named num that you never use. Even worse, you have a parameter in AddItem with the same name. Are you sure it does what you want? The same is true for growth. I would advise you to name your member variable differently, so that you know what they are quickly. I prefixe them with "m_" for example, but you can do as you wish.
You do not need to declare your function parameters inside your class. Only in the function prototype.
Then, in your AddItem function, you use your variable Size to determine where to add the new element, but you initialize your array with it too, which means that not only you do not add your elements at the beginning of your array, you try to write them in memory you do not own!
I could continue for a long time. I am sorry but it only appears to me that you do not know C++ at all. You should go learn the basics again, and maybe start with an easier project to begin your C++ learning.
Good luck :-)

Class Rolling Dice program

I need to write C program for rolling dice using class Dice. The main requirement is that I need to use this main, editing it:
int main()
{
Dice* ptrDice;
???
for (int i = 0; i < 5; i++)
{
???? // roll the 5 dice
???? // print the outcome
}
}
I just cannot get how to use pointers here. Can anyone help, pls?!
Here is my code but it's not working :(
#include <iostream>
#include <iomanip>
#include <cstdlib>
using namespace std;
class Dice{
public:
Dice();
int getNums();
void Roll();
private:
int nNums;
};
Dice::Dice(){
nNums=5;
}
int Dice::getNums()
{
return nNums;
}
void Dice::Roll()
{
nNums = rand()%6 + 1;
}
int main()
{
Dice* ptrDice = new Dice;
ptrDice -> getNums();
for (int i = 0; i < 5; i++)
{
getNums[i] = rand()%6 + 1; // roll the 5 dice
cout << "You rolled: ";
cout << ptrDice->getNums() << setw(4);
cout << endl; // print the outcome
}
}
My main trouble is to use that ptrDice and printing it in main function, I guess!
You're making this more complicated than it needs to be.
A simple Dice object needs no data members and only one member function. If you're using the rand() function, the constructor should seed the random number generator with srand(seed). The Roll() function should return the number rolled as an int. You don't need the getNums() function at all, which will only return 5 as your class is defined.
class Dice() {
public:
int roll() { return rand() % 6 + 1; }
};
...
int main() {
Dice* ptrDice = new Dice;
for (int i=0; i<5; i++) {
cout << "You rolled" << ptrDice->roll() << '\n';
}
delete ptrDice;
}
You could expand this class to simulate multiple dice with any number of sides. Then you could use integer data members to retain the number of dice and their number of sides.

C++ Dynamic Array of Objects Sorting by Property

I'm trying to implement selection sort as a member function within class, to sort the objects of the class where the number of total players are being got by user input, also the names and scores of the players are being got by user too.
I'll sort the player objects by the property of their scores, which is a class member, being got by user input.
My problem is, i got stuck within the main where i can't call the class' member function sort for the array of objects.
class Player{
private:
string name;
int score;
public:
void setStatistics(string, int) // simple setter, not writing the whole function
void sortPrint(int, Player []);
int getScore(){ return score; }
void print(){ cout << name << " " << score << endl; }
};
void Player::sortPrint(int n, Player arr[]){
int i, j, minIndex;
Player tmp;
for (i = 0; i < n - 1; i++) {
int maxIndex = i;
for (j = i + 1; j < n; j++)
{
if (arr[j].getScore() > arr[minIndex].getScore())
{
minIndex = j;
}
}
if (minIndex != i) {
tmp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = tmp;
}
for(int i=0; i<n; i++){
arr[i].print(); // not sure with this too
}
}
};
int main(){
int n,score;
string name;
cout << "How many players ?" << endl;
cin >> n;
Player **players;
players = new Player*[n];
for(int i=0;i<n;i++) {
cout << "Player's name :" << endl;
cin >> name;
cout << "Player's total score:" << endl;
cin >> score;
players[i] = new Player;
players[i]->setStatistics(name,score);
}
for(int i=0; i<n;i++){
players->sortPrint(n, players); // error here, dont know how to do this part
}
// returning the memory here, didn't write this part too.
}
Try to replace void Player::sortPrint(int n, Player arr[]) with void Player::sortPrint(int n, Player*) and call function like players->sortPrint(n, *players)
Your problem is, that players is a pointer to array of Player, and arrays do not have member functions of the containees. As Player::sortPrint does not depend on the object itself, declare it as static and call it like Player::sortPrint(n, players);
Unless you have a very good reason not to, you should use std::sort rather than your own sorting algorithm. You should use a comparison function which compares the score of each player.
The following should work in C++03:
bool comparePlayerScores(const Player* a, const player* b)
{
return (a->getScore() < b->getScore());
}
// Returns the players sorted by score, in a new std::vector
std::vector<Player*> getSortedPlayers(Player **players, int num_players)
{
std::vector<Player*> players_copy(players, players + num_players);
std::sort(players_copy.begin(), players_copy.end(), comparePlayerScores);
return players_copy;
}
void printSorted(Player **players, int num_players)
{
std::vector<Player*> sorted_players = getSortedPlayers(players, num_players);
// Could use iterators here, omitting for brevity
for (int i = 0; i < num_players; i++) {
sorted_players[i]->print();
}
}
(Alternatively, you could define an operator< on your Player class which compares scores, which would let you store players in a std::set or std::map.)