Need Help Operator Overloading So I Can Display Functions - c++

I'm stuck trying to figure out how to overload the << operator so I can display my rational class functions.
These are the lines I'm trying to overload:
cout << "Testing the compare() member function, found:" << endl;
if (r1.compare(r2) == 1)
cout << r1.display() << " is greater than " << r2.display() << endl;
else if (r1.compare(r2) == 0)
cout << r1.display() << " is equal to " << r2.display() << endl;
else if (r1.compare(r2) == -1)
cout << r1.display() << " is less than " << r2.display() << endl;
cout << "Testing the four arithmetic member functions:" << endl;
cout << "r1 + r2 = " << r1.display() << " + " << r2.display() << " = " << r1.add(r2) << endl;
cout << "r1 - r2 = " << r1.display() << " - " << r2.display() << " = " << r1.subtract(r2) << endl;
cout << "r1 * r2 = " << r1.display() << " * " << r2.display() << " = " << r1.multiply(r2) << endl;
cout << "r1 / r2 = " << r1.display() << " / " << r2.display() << " = " << r1.divide(r2) << endl;
The errors occur everytime I call a function. Here is the code for the functions:
void rational::display()
{
int gcd = GCD();
if (denom < 0)
{
num = -num;
cout << num / gcd << " / " << denom / gcd << endl;
}
else if (num == 0)
cout << num << endl;
}
rational rational::add(const rational &r2) const
{
rational sum;
sum.num = (num * r2.denom) + (r2.num * denom);
sum.denom = denom * r2.denom;
return sum;
}
The multiply, divide, and subtract functions are as same as the add they just have the symbols and variable name changed to match the operation. My overload operator is set up like this:
ostream& operator<< (ostream& out, rational &robj)
{
out << example code << example code;
return out;
}
Any help would be appreciated. This is my first time posting so if I need to post more of my code I will. Thanks!

First of all, change
ostream& operator<< (ostream& out, rational &robj)
to
ostream& operator<< (ostream& out, rational const& robj)
Then, instead of
cout << r1.display() << " is greater than " << r2.display() << endl;
use
cout << r1 << " is greater than " << r2 << endl;
Since you already have the above operator<< function, I would get rid of the member function display(). It doesn't (should not) give you any more functionality than using the operator<< function.
Given
rational 1
Use of
r.display();
should give you the same output as
cout << r << endl;
See What are the basic rules and idioms for operator overloading? for more details on operator overloading.

Related

C++ proper usage of ostream inside a class and passing arguments?

I've recently started learning c++ and for the life of me, I can't seem to get the syntax of using ostream in a class and what arguments should I pass. Here's the code:
This is the class in question:
#include <iostream>
#include <string>
using namespace std;
class Pokemon{
friend ostream& operator<<(ostream&, Pokemon);
public:
string name, level, cp;
Pokemon(string x="Pikachu", string y="5", string z="1000"){
name = x;
level = y;
cp = z;
}
Pokemon name(){
return this->name;
}
Pokemon level(){
return this->level;
}
Pokemon cp(){
return this->cp;
}
Pokemon display_stats(){
cout << this-> name << "stats are:" << endl;
cout << " " << "Attack: 2716.05" << endl;
cout << " " << "Defence: 1629.63" << endl;
cout << " " << "HP: 1086.42" << endl;
}
};
template<typename TYPE> //i dont understand this and the things i've written down here are only based on samples i've seen
ostream& operator<<(ostream& os, Pokemon & c){
os << "The level of " << c.name << " is" << c.level << " with cp of " << c.cp;
}
As you could see, I already tried constructing the ostream thing but I don't really understand how it works. This is my main function:
int main()
{
Pokemon a, b, c, d;
a = Pokemon();
b = Pokemon("Weezing");
c = Pokemon("Nidoking", 100);
d = Pokemon("Mewtwo", 50, 5432.1);
cout << a << endl;
cout << b << endl;
cout << c << endl;
cout << d << endl;
cout << "Jessie: You are no match to me! Go " << b.name << "!" << endl;
cout << "Gary: Go lvl " << c.level << " " << c.name << "! Crush them" << endl;
cout << "Ash: " << a.name << " can do it even thouh he is only level " << a.level << endl;
cout << "Jessie: Hahaha! My " << b.name << " CP is " << b.cp << endl;
cout << "Gary: "<< c.name << " CP is " << c.cp << endl;
cout << "Ash: " << a.name << " CP is " << a.cp << endl;
cout << "Giovanni: Behold " << d.name << " is here." << endl;
d.display_stats();
return 0;
}
I'm getting errors of:
no instance of constructor "Pokemon::Pokemon" matches the argument list -- argument types are: (const char [9], int) //on line c = Pokemon("Nidoking", 100);
no instance of constructor "Pokemon::Pokemon" matches the argument list -- argument types are: (const char [7], int, double) //on line d = Pokemon("Mewtwo", 50, 5432.1);
All of your Pokemon class methods are returning the wrong type. And your main() is not calling any of the methods correctly at all.
Change your Pokemon class to look more like this:
#include <iostream>
#include <string>
using namespace std;
class Pokemon {
private:
string m_name;
int m_level;
double m_cp;
friend ostream& operator<<(ostream&, const Pokemon&);
public:
Pokemon(string x="Pikachu", int y=5, double z=1000) {
m_name = x;
m_level = y;
m_cp = z;
}
string name() const {
return m_name;
}
int level() const {
return m_level;
}
double cp() const {
return m_cp;
}
void display_stats() const {
cout << m_name << " stats are:" << endl;
cout << " " << "Attack: 2716.05" << endl;
cout << " " << "Defense: 1629.63" << endl;
cout << " " << "HP: 1086.42" << endl;
}
};
ostream& operator<<(ostream& os, const Pokemon &c) {
os << "The level of " << c.m_name << " is " << c.m_level << " with cp of " << c.m_cp;
return os;
}
And then change main() to look more like this:
int main()
{
Pokemon a;
Pokemon b("Weezing");
Pokemon c("Nidoking", 100);
Pokemon d("Mewtwo", 50, 5432.1);
cout << a << endl;
cout << b << endl;
cout << c << endl;
cout << d << endl;
cout << "Jessie: You are no match to me! Go " << b.name() << "!" << endl;
cout << "Gary: Go lvl " << c.level() << " " << c.name() << "! Crush them" << endl;
cout << "Ash: " << a.name() << " can do it even though he is only level " << a.level() << endl;
cout << "Jessie: Hahaha! My " << b.name() << " CP is " << b.cp() << endl;
cout << "Gary: " << c.name() << " CP is " << c.cp() << endl;
cout << "Ash: " << a.name() << " CP is " << a.cp() << endl;
cout << "Giovanni: Behold " << d.name() << " is here." << endl;
d.display_stats();
return 0;
}
Live Demo

Creating a Simple Calculator, having an issue with the addition

I'm trying to create a simple calculator and i already encountered an issue when addition is being used. I created a function for addition and whenever i pass in two values i get a different answer. For Example when i add 4,5 i would expect to get 9 but the answer i get is 0029144C . Im still a beginner, so at first i wasn't sure if using type bool for the adding function would affect my result, but i changed it to type float and still getting the same result (in case anyone asks).
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
void SimCalcMenu();
void additionSign();
bool makeSum(float num1, float num2);
int main() {
float firstNum, SecondNum;
char operationLetter;
SimCalcMenu();
cout << " Please Select an Operation You Would Like to Perform ";
cin >> operationLetter;
if (operationLetter == 'a' || operationLetter == 'A')
{
additionSign();
cout << " Enter the First Number : ";
cin >> firstNum;
cout << " Enter the Second Number: ";
cin >> SecondNum;
makeSum(firstNum, SecondNum);
cout << " The Sum of " << firstNum << " and " << SecondNum << " is :" << makeSum << endl;
}
else
{
cout << " Error ";
}
return 0;
}
void SimCalcMenu() {
cout << "------------------------------------------------------------------------------" << endl;
cout << " WELCOME TO SIM CALCULATOR " << endl;
cout << "------------------------------------------------------------------------------" << endl;
cout << endl;
cout << " Please Select an Operation : " << endl;
cout << " A.) Addition " << endl;
cout << " B.) Subtraction " << endl;
cout << " C.) Multiplication " << endl;
cout << " D.) Division " << endl;
cout << " E.) Roots ( Only Positive Number)" << endl;
cout << " F.) Power ( Only Positive Number " << endl;
cout << " G.) Percentage " << endl;
cout << " H.) Display functions execution " << endl;
cout << " I.) Quit " << endl;
cout << "------------------------------------------------------------------------------" << endl;
}
void additionSign() {
cout << "------------------------------------------------------------------------------" << endl;
cout << " ADDITION " << endl;
cout << "------------------------------------------------------------------------------" << endl;
}
bool makeSum(float num1, float num2) {
float totSum;
totSum = num1 + num2;
return totSum;
}
makeSum() should return float, because you are returning the sum of two floats.
You are not getting the right result because you are printing makeSum, which is the address of the function. You want to print the value of makeSum(firstNum, SecondNum).
this line
cout << " The Sum of " << firstNum << " and " << SecondNum << " is :" << makeSum << endl;
IS 'printing' 'makesum', makesum is a function so its printing the address of makesum
you need
cout << " The Sum of " << firstNum << " and " << SecondNum << " is :" << makeSum(firstNum, SecondNum) << endl;
now at least it will print the result of makesum. As other have pointerd out that function is wrong (it returns a bool).
should be
float makeSum(float num1, float num2) {
float totSum;
totSum = num1 + num2;
return totSum;
}

C++ - Multiplying / adding, two integers, then determining if they are even or odd

I'm having trouble with a simple program which will multiply 2 integers and print the output determining if it is even or odd. It also will add the 2 integers input in the beginning and do the same on the following line. The multiplying works fine and displays if the product is even or odd properly. However, the addition is not doing so and I am not understanding why. Here is my code:
#include <iostream>
using namespace std;
int main (){
int a, b;
cout << "Please enter an integer: ";
cin >> a;
cout << "Please enter another integer: ";
cin >> b;
if (a*b %2== 0){
cout << "The product of " << a << " and " << b << " is " << (a*b)
<< " and is even." << endl;
}
else {
cout << "The product of " << a << " and " << b << " is " << (a*b)
<< " and is odd." << endl;
};
if (a+b %2== 0){
cout << "The sum of " << a << " and " << b << " is " << (a+b)
<< " and is even." << endl;
}
else {
cout << "The sum of " << a << " and " << b << " is " << (a+b)
<< " and is odd." << endl;
}
return (0);
}
Any help and an explanation would be greatly appreciated. Thanks!
Operator Precedence
Basically, % is dealt with before +, so your test:
if (a+b % 2 == 0)
works out like
if (a + (b%2) == 0)
which doesn't make a whole lot of sense, and is rarely going to be true, unless both b is even and a is 0.
All the operations that are to do with multiplication (*, /, %) have the same precedence, and are handled from left-to-right, so
if (a*b % 2 == 0)
works out ok, as:
if ((a*b) % 2 == 0)
which happens to be what you really meant.
However, these multiplication operations are handled before the operations related to addition (+, -). So % is grouped before +, causing your specific problem.
You may have learnt about order of operations in school, for instance I was taught BODMAS. Same rules apply in C++.
Personally, I find it's best to use parentheses liberally in any sort of compound expression, even when it's not strictly necessary. It can make the code a lot easier to read, rather than trying to remember all the rules in your head. So I would prefer:
if ((a*b) % 2 == 0) // ...
if ((a+b) % 2 == 0) // ...
even though the extra parentheses in the first aren't really required.
Operator precedence says that % comes before + so
a+b %2== 0
Is actually
a + (b % 2) == 0
You need to wrap the addition with ()
(a + b) % 2 == 0
Possibly Order of Operations.
To ensure that your code is behaving the way you intend, you may wish to rewrite it like this:
if (((a*b) %2)== 0){
cout << "The product of " << a << " and " << b << " is " << (a*b) << " and is even." << endl;
}
else {
cout << "The product of " << a << " and " << b << " is " << (a*b) << " and is odd." << endl;
};
if (((a+b) %2)== 0){
cout << "The sum of " << a << " and " << b << " is " << (a+b) << " and is even." << endl;
}
else {
cout << "The sum of " << a << " and " << b << " is " << (a+b) << " and is odd." << endl;
}
You can then incrementally remove parenthesis until you're confident that the code is readable but still correct.

trying to order 3 values from least to greatest C++

I have a program that takes numbers that a person enters and sums it.
This happens 3 times, so I have 3 totals. The problem I am having is that I need to order them from greatest to least no matter what the sums come out to be.(this isnt the full code assume the sums are calculated and are declared)
#include <iostream>
#include <string>
using namespace std;
string firstName1, lastName1; // input and output for the users names
string firstName2, lastName2;
string firstName3, lastName3;
// from greatest to least
if ( sum > sum_2 > sum_3 )
{
cout << "Total for" << " " << firstName1 << " " << lastName1 << " " << "$" << sum << ".00" << endl;
cout << "Total for" << " " << firstName2 << " " << lastName2 << " " << "$" << sum_2 << ".00" << endl;
cout << "Total for" << " " << firstName3 << " " << lastName3 << " " << "$" << sum_3 << ".00" << endl;
}
In c++, the syntax sum > sum_2 > sum_3 won't evaluate as you're assuming. It's equivalent to (sum > sum_2) > sum_3.
In the case where sum is greater than sum_2, sum > sum_2 will evaluate to true. Then, this boolean value will be converted to an integer, 1 and compared with sum_3.
To do what you're trying to accomplish try:
if (sum > sum_2 && sum_2 > sum_3)
Use a helper swap function:
void swap( int *a, int *b )
{
int temp = *a;
*a = *b;
*b = temp;
}
And bubble sort it:
int sums[3] = { sum, sum_2, sum_3 };
for ( int i = 0; i < 3; ++i )
for ( int j = 0; j < i; ++j )
if ( sums[j] < sums[i] )
swap( &sums[j], &sums[i] );
cout << "Total for" << " " << firstName1 << " " << lastName1 << " " << "$" << sums[0] << ".00" << endl;
cout << "Total for" << " " << firstName2 << " " << lastName2 << " " << "$" << sums[1] << ".00" << endl;
cout << "Total for" << " " << firstName3 << " " << lastName3 << " " << "$" << sums[2] << ".00" << endl;

no match for 'operator <<' in 'std::operator<<

void printAst(int x)
{
for( int i = 0; i < x; i++)
{
cout << "*";
}
cout << " (" << x << ")" << endl;
}
void printHisto(int histo[])
{
//cout.precision(3);
int count = 0;
for(double i = -3.00; i < 3.00; i += 0.25)
{
cout << setprecision(3) << i << " to " << i + 0.25 << ": " << printAst(histo[count]) << endl;
// cout << setw(3) << setfill('0') << i << " to " << i + 0.25 << ": " << histo[count] << endl;
count ++;
}
}
I want my output to be formatted like this, so I used setprecision(3), which also does not work.
-3.00 to -2.75: (0)
-2.75 to -2.50: * (1)
-2.50 to -2.25: * (1)
-2.25 to -2.00: * (6)
-2.00 to -1.75: ***** (12)
So instead it is formatted like this
-3 to -2.75: 3
-2.75 to -2.5: 4
-2.5 to -2.25: 5
-2.25 to -2: 0
-2 to -1.75: 0
The main problem however, is that when I try to call printAst on to histo[count]. This is what is causing this error. PrintAst is used to print the asteriks, histo[count] provides the amount of asteriks to print.
cout << setprecision(3) << i << " to " << i + 0.25 << ": " << printAst(histo[count]) << endl;
You seem to have a misunderstanding about how chaining << works in streams.
cout << 42 looks like an operator expression with two operands, but it's really a call to a function with two parameters (the name of the function is operator<<). This function returns a reference to the stream, which enables the chaining.
An expression like this:
cout << 1 << 2;
is equivalent to this:
operator<<( operator<<(cout, 1), 2);
Now, the problem is that a parameter to a function can't be void but that's what printAst returns. Instead, you need to return something that can be streamed - in other words, something that operator<< is already overloaded for. I'd suggest std::string:
std::string printAst(int x);
{
std::string s = " (" + std::string(x,'*') + ")";
return s;
}
You can read more about operator overloading.