I'm working on a project, and I've finally gotten it to the point where it does everything I want and produces the output I want. The problem however is that my method of output is not done by the method that is required for the project. Currently I'm just using a function within my one of my classes to print the histogram of die roll occurrences, but for the project we are supposed to use a function where we overload the << operator with the following header :
"This stand-alone function should have the signature:
This function will allow you to perform the following:
cout << hist << endl; // Where hist is a histogram"
I've included my code below ( I've omitted the .cpp and .h file for the part where it rolls two die instead of one to keep it brief). Not really sure how I can simply modify the code I already have to meet this requirement. Any help will be greatly appreciated.
#include <stdlib.h>
#include <time.h>
#include <vector>
#include <algorithm>
# include <iostream>
using namespace std;
class aDie
{
public:
int roll(); //return an integer between 1 and 6 to represent what face appears when the die is rolled.
aDie(); //Default constructor
~aDie(); //Destructor
private:
int faces = 6;
};
aDie.cpp---------------------------------------------------------------------
#include "aDie.h"
using namespace std;
int aDie::roll(){
return ((rand() % faces) + 1); //returns a number 1-6 randomly
}
aDie::aDie(){
cout << "Dice Roll....." << endl;
return;
}
aDie::~aDie(){
return;
}
aHistogram.h---------------------------------------------------------------
#define AHISTOGRAM_H_INCLUDED
#include <algorithm>
#include <stdlib.h>
#include <vector>
# include <iostream>
using namespace std;
class aHistogram{
public:
void update(int face);
void display(int maxLengthOfLine);
int Count(int face);
void reset();
aHistogram(); //Constructor
~aHistogram(); //Destructor
vector<int> histogram;
private:
const int Faces = 6;
int totalRolls;
double bigVal = 0.0;
double xScaler;
int face = 0;
int maxLengthOfLine = 0;
};
aHistogram.cpp-----------------------------------------------------------------
//Adds a count to each face every time the die lands on said face.
#include "aHistogram.h"
void aHistogram::update(int face){
histogram.at(face)++;
return;
}
//Displays the histogram with x's representing occurences, with the largest value of occurences displaying 60 x's
//maxLengthOfLine represents the maximum number of x’s to be printed for the largest count.
void aHistogram::display(int maxLengthOfLine)
{
xScaler = bigVal / maxLengthOfLine;
for (int i = 1; i <= 6; i++)
{
cout << i << ":" << Count(i) << " occurences: ";
int numXs = histogram.at(i) / xScaler;
for (int j = 0; j < numXs; j++)
{
cout << "x";
}
cout << endl;
}
}
//To be called AFTER aHistogram::update
//Returns a count of how many times for each face of the die
int aHistogram::Count(int face)
{
//For Loop determines the largest count
for (int i = 1; i <= Faces; i++)
{
while (histogram.at(i) > bigVal)
{
bigVal = histogram.at(i);
}
}
//
return histogram.at(face);
}
void aHistogram::reset()
{
histogram.clear();
return;
}
//Defines the DEFAULT CONSTRUCTOR. Sets all elements of the histogram to zero.
aHistogram::aHistogram() : histogram(7), Faces(6), maxLengthOfLine(60)
{
}
//Defines the DESTRUCTOR. Clears vector after use.
aHistogram::~aHistogram()
{
histogram.clear(); //Clears vector
return;
}
main.cpp----------------------------------------------------------
#include <algorithm>]
#include "aDie.h"
#include "aHistogram.h"
#include "aHistogramTwo.h"
using namespace std;
int main()
{
int seedNum;
cout << "enter a seed number" << endl;
cin >> seedNum;
srand(seedNum);
int numRolls;
const int maxLengthOfLine = 60;
cout << "How many rolls? " << endl;
cin >> numRolls;
aDie oneDie;
aHistogram oneHistogram;
aHistogramTwo twoHistogram;
//For Loop rolls the die and updates the histogram vector Histogram.
for (int i = 0; i < numRolls; i++)
{
int face = oneDie.roll();
int faceTwo = oneDie.roll();
oneHistogram.update(face);
oneHistogram.Count(face);
twoHistogram.update(face, faceTwo);
twoHistogram.Count(face);
}
cout << "Histogram: " << endl;
oneHistogram.display(maxLengthOfLine);
cout << " " << endl;
cout << "Two Die Histogram : " << endl;
twoHistogram.display(maxLengthOfLine);
system ("pause");
}
You have a function: void aHistogram::display( int maxLengthOfLine )
That outputs to stream std::cout.
You want a function: ostream& operator<<( ostream& os, const aHistogram& hist )
That outputs to stream os.
What members of aHistogram does display() use?
The operator has to access that same data of the 'hist' object.
Can it do that via the public interface of aHistogram?
Do you have to resort to declaring the operator a friend of the class?
Well display() is using the private members xScaler, and bigVal, so it will be necessary to declare the operator a friend of the class. Was just messing around with it a little to see if I could get it to output something basic and its giving me the error: " Error C2679 binary '<<': no operator found which takes a right-hand operand of type 'oStream' (or there is no acceptable conversion) "
I'm completely new to using this type of function so please bear with me if I'm missing something obvious. What am I doing wrong here? Still not really sure how to get this to do what I need it to.
Ok I think I've gotten how to write out the code in general, but now it's just printing that there are 0 occurrences of each face. What dumb mistake am I making here?
//aHistogram.h
#define AHISTOGRAM_H_INCLUDED
#include <algorithm>
#include <stdlib.h>
#include <vector>
# include <iostream>
usingnamespace std;
class aHistogram{
public:
void update(int face);
void display(int maxLengthOfLine);
int Count(int face);
void reset();
aHistogram(); //Constructor
~aHistogram(); //Destructor
vector<int> histogram;
friend ostream& operator<<(ostream& os, aHistogram& hist);
private:
constint Faces = 6;
int totalRolls;
double bigVal = 0.0;
double xScaler;
int face = 0;
int maxLengthOfLine = 0;
};
//aHistogram.cpp
//increments a count for each face every time the die lands on that face
#include "aHistogram.h"
void aHistogram::update(int face){
histogram.at(face)++;
return;
}
ostream& operator<<(ostream& os, aHistogram& hist)
{
hist.xScaler = hist.bigVal / hist.maxLengthOfLine;
for (int i = 1; i <= 6; i++)
{
os << i << ":" << hist.Count(i) << " occurences: ";
int numXs = hist.histogram.at(i) / hist.xScaler;
for (int j = 0; j < numXs; j++)
{
os << "x";
}
os << endl;
}
return os;
}
//prints an x for numXs occurences of each face.
//maxLengthOfLine represents the maximum number of x’s to be printed for the largest count.
void aHistogram::display(int maxLengthOfLine)
{
xScaler = bigVal / maxLengthOfLine;
for (int i = 1; i <= 6; i++)
{
cout << i << ":" << Count(i) << " occurences: ";
int numXs = histogram.at(i) / xScaler;
for (int j = 0; j < numXs; j++)
{
cout << "x";
}
cout << endl;
}
}
//called after update()
//returns a count for how many times each face occurs
int aHistogram::Count(int face)
{
//For Loop determines the largest amount of occurences of a face
for (int i = 1; i <= Faces; i++)
{
while (histogram.at(i) > bigVal)
{
bigVal = histogram.at(i);
}
}
//
return histogram.at(face);
}
void aHistogram::reset()
{
histogram.clear();
return;
}
//Defines the default constructor
aHistogram::aHistogram() : histogram(7), Faces(6), maxLengthOfLine(60)
{
}
//Defines the destructor, which clears the vector after being used
aHistogram::~aHistogram()
{
histogram.clear(); //Clears vector
return;
}
//main.cpp
int main()
{
int seedNum;
cout << "enter a seed number" << endl;
cin >> seedNum;
srand(seedNum);
int numRolls;
constint maxLengthOfLine = 60;
cout << "How many rolls? " << endl;
cin >> numRolls;
aDie oneDie;
aHistogram oneHistogram;
aHistogramTwo twoHistogram;
// Loop rolls the die and updates the vector Histogram for each roll.
for (int i = 0; i < numRolls; i++)
{
int face = oneDie.roll();
int faceTwo = oneDie.roll();
oneHistogram.update(face);
oneHistogram.Count(face);
twoHistogram.update(face, faceTwo);
twoHistogram.Count(face);
}
cout << "Histogram: " << endl;
/*
oneHistogram.display(maxLengthOfLine);
cout << " " << endl;
cout << "Two Die Histogram : " << endl;
twoHistogram.display(maxLengthOfLine);
*/
aHistogram hist;
aHistogramTwo histTwo;
cout << hist << endl;
cout << "Two Die Histogram: " << endl;
cout << histTwo << endl;
system ("pause");
}
Nevermind, figured it out. Solution was to change the loop in main.cpp from,
This:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
for (int i = 0; i < numRolls; i++)
{
int face = oneDie.roll();
int faceTwo = oneDie.roll();
oneHistogram.update(face);
oneHistogram.Count(face);
twoHistogram.update(face, faceTwo);
twoHistogram.Count(face);
}
To:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
for (int i = 0; i < numRolls; i++)
{
int face = oneDie.roll();
int faceTwo = oneDie.roll();
hist.update(face);
hist.Count(face);
histTwo.update(face, faceTwo);
histTwo.Count(face);
}
How many rolls are you doing? Line 51 and the integer division therein may result in a 0 value of bigVal is less than maxLengthOfLine which will happen for smaller sample numbers.
And, since you're nearing the end, here's something to compare to: