Function call priority in output stream - c++

So, I have the following class:
typedef double decimal;
class Ratio {
int num, den;
decimal val;
public:
Ratio() { num = 1, den = 1, val = (decimal)num / den; }
Ratio update(int a, int b) {
num *= a, den *= b;
val = (decimal)num / den;
return *this;
}
decimal v(void) { return val; }
friend ostream &operator<<(ostream &out, const Ratio &R) {
return (out << R.num << ':' << R.den);
}
};
When I use the member functions in the output stream as:
cout<<"R = "<<R.update(2,1)<<"\tvalue = "<<R.v();
where R is of type Ratio, the function to the right end is called first so it displays the updated ratio but the non-updated value:
R = 2:1 value = 1
I overcame this by splitting the stream in two:
cout<<"R = "<<R.update(2,1), cout<<"\tvalue = "<<R.v();
so that I "force" .update() to be called first. Is there another way to achieve this, using only one stream for output?

As there is no guaranteed evaluation order in c++, it won't work without splitting it into separate parts, as you did in your fix.
Quoting from cppreference
There is no concept of left-to-right or right-to-left evaluation in C++. This is not to be confused with left-to-right and right-to-left associativity of operators: the expression a() + b() + c() is parsed as (a() + b()) + c() due to left-to-right associativity of operator+, but the function call to c may be evaluated first, last, or between a() or b() at run time
As user #super pointed out, starting from c++17 the evaluation order of shift operators is now defined. It's hidden in bullet 19) of the rules on the page I linked above. So if you can c++17, you're done.

Put value also in << overloaded function like
friend ostream& operator<<(ostream &out,const Ratio &R){return (out<<"R = "<<R.num<<':'<<R.den<<"\tvalue = "<<R.val);}
Now
#include<iostream>
using namespace std;
typedef double decimal;
class Ratio{
int num,den;
decimal val;
public:
Ratio(){num=1,den=1,val=(decimal)num/den;}
Ratio update(int a,int b){
num*=a,den*=b;
val=(decimal)num/den;
return *this;
}
friend ostream& operator<<(ostream &out,const Ratio &R){return (out<<"R = "<<R.num<<':'<<R.den<<"\tvalue = "<<R.val);}
};
int main()
{
Ratio R;
cout<<R.update(2,1)<<endl;
}
Output:
R = 2:1 value = 2
Process returned 0 (0x0) execution time : 0.382 s
Press any key to continue.

Related

Why type conversion does not work with += operator?

I wrote the following code as a practice for my OOP exam:
#include <iostream>
using namespace std;
class doble
{
public:
doble(double D):d(D){}
inline operator double(){return d;}
private:
double d;
};
int main()
{
doble a = 1.5, b = 10.5;
doble c = 5.25, d = c;
cout << c / d * b + b * c - c * c / b + b / c << endl; //65
d = a = b += c;
cout << d <<" "<< a <<" "<< b <<" "<< c << endl; //15,75 15,75 15,75 5,25
}
I get an error in the line with the operator '+=' that says: 'no operator "+=" matches these operands'.
I don't know what else can I do because the overloading of arithmetic operators, assignment, insertion, or the use of friendly functions is not allowed in this exercise.
Thank you!
I thought that with the conversion to double, the operator '+=' will work with doble.
Your example works if you defined the operator += properly.
doble& operator += ( const doble& rhs ) {
d += rhs.d;
return *this;
}
Produces
Program stdout
65
15.75 15.75 15.75 5.25
Godbolt: https://godbolt.org/z/rnsMf7aYh
I thought that with the conversion to double, the operator '+=' will work with doble.
The problem is that both of the operands b and c are of the same type so there is no type conversion to double required here. Moreover, since you've not overloaded operator+= for doble, it produces the mentioned error.
I don't know what else can I do
To solve this you can overload operator+=:
#include <iostream>
class doble
{
public:
doble(double D):d(D){}
inline operator double(){return d;}
//overload operator+=
doble& operator+=(const doble& rhs)
{
/* addition of rhs to *this takes place here */
d+=rhs.d;
return *this; // return the result by reference
}
private:
double d;
};
int main()
{
doble b = 10.5;
doble c = 5.25;
b += c;
std::cout << b << c;
}
Demo

return float when + class

I was trying to take float + objected class and have the result return as float, however, my code just does not work. I am pretty confused. I have added that overload function as a friend to the class. could anyone explain it to me?
With the best regards
#include <iostream>
#include <cstdint>
using namespace std;
#define MAX_NUM_SENSORS 5
enum { INVALID, TEMPERATURE, HUMIDTY };
// The 'Sensors' structure describes a single sensor, it's type and current value.
// type - describes the type of sensor 0 (INVALID), 1 (TEMPERATURE), 2 (HUMIDITY)
// value - the current value of the sensor.
// valid - set to TRUE if the sensor is valid, should default to FALSE until set up.
class Sensors
{
public:
friend ostream& operator <<(ostream&, const Sensors&);
friend float operator+ (float,const Sensors&);
private:
int type;
float value;
bool valid = false;
};
ostream& operator<<(ostream& OutStream, const Sensors& OutComp)
{
OutStream << " Type: " << (OutComp.type == TEMPERATURE ? "Temperature" : "Humidity");
OutStream << " Value: " << OutComp.value << endl;
return OutStream;
}
float operator+ (float adding, const Sensors& added)
{
float sum;
sum = added.value + adding;
return sum;
}
int main()
{
Sensors tested();
float m = 1.2 + tested;
cout << m;
return 1;
}
I ran your code in godbolt
There is some kind of simple fixes.
int main()
{
Sensors tested();
// ^--- remove this parenthesis (or use braces, it's ambigious)
float m = 1.2 + tested;
// ^----- This is a double, change this to "1.2f"
cout << m;
return 1;
}
Decimal values in code is double by default, you need to add the postfix f to specify that it is a float. Or you could add a definition of operator + with double as a parameter.
Here is a compiling version of your code

Add fractions using operator overloading

In an interview I was asked to create two classes. The first abstract class is called Number, which supports one operation “+”. And the other one fraction which implements the "Number" abstract class.
Further: For a Fraction once added, it needs to be displayed in its original form. That is, 2/4 has to be displayed as “2/4”, not “1/2” or “0.5”.
No Other detail was provided to me.
Below is what I had tried (Incomplete).
My main.cpp
#include <iostream>
#include "Fraction.h"
using namespace std;
int main()
{
Fraction sumFraction;
Fraction n11(1,2);
Fraction n21(1,2);
cout << n11.getValuenum() << "/";
cout << n11.getValueden() << endl;
cout << n21.getValuenum() << "/";
cout << n21.getValueden() << endl;
sumFraction = n11 + n21;
cout << sumFraction.getValuenum() << endl;
cout << sumFraction.getValueden() << endl;
return 0;
}
My Numbers.h // ABSTRACT CLASS
#pragma once
template<class T>
class Number
{
virtual T& operator= (const T &) = 0; // first parameter is implicitly passed
virtual const T operator+ (const T &) = 0;
virtual void display() = 0;
};
My Fraction.cpp
#include "Fraction.h"
int Fraction::getValuenum()
{
return this->a1;
}
int Fraction::getValueden()
{
return this->a2;
}
Fraction::Fraction()
{
a1 = 0;
a2 = 0;
}
Fraction::Fraction(int num, int den)
{
a1 = num;
a2 = den;
}
void Fraction::display()
{
// will display the number in its original form
}
Fraction& Fraction::operator=(const Fraction &num)
{
a1 = num.a1;
a2 = num.a2;
return *this;
}
const Fraction Fraction::operator+(const Fraction &numberTwo)
{
Fraction n1;
n1.a1 = this->a1*numberTwo.a2 + this->a2*numberTwo.a1;
n1.a2 = this->a2*numberTwo.a2;
return n1;
}
My Fraction.h
#pragma once
#include "Number.h"
class Fraction : public Number<Fraction>
{
private:
int a1;
int a2;
public:
void display();
Fraction();
Fraction(int num, int den);
int getValuenum();
int getValueden();
Fraction& operator= (const Fraction &); // first parameter is implicitly passed
const Fraction operator+ (const Fraction &); // first parameter is implicitly passed
};
Below are my question:
Do I really need to pass numerator and denominator separately from my Main function for each fraction. Currently, I am passing it as separately to keep track of numerator and denominator which might be helpful while adding and returning the result in terms for fraction.
With my operator + logic if I add 1/4+1/4 I get 8/16, what is expected is I guess 2/4 which we get if we add normally. So how to add using numerator and denominator and to keep the fraction in such a way, so that if output is 2/4 then 2/4 and not 1/2 or 0.5.
Please help me.
Some remarks:
you should not allow the denominator to be 0 because it gives an inexistent number (infinity or undeterminated)
you should definitely not initialize the denominator to 0 for same reason (1 seems a more reasonable value)
the correct (mathematical) addition of fractions is (*):
a/b + c/d = (ad +bc)/bd
Instead of (or in addition to) the display method, I would advise you to write a ostream& operator << (ostream&, const Fraction&) overload. That would allow you to just write in you main
std::cout << n11 << " + " << n21 << " = " << sumFraction << std::endl;
I did not really understand you first question, but I would add a conversion from an int:
Fraction(int n): a1(n), a2(1) {};
to allow to write directly Fraction(1, 2) + 1 or Fraction(1) + Fraction(1/2) (the first element of the addition must be a Fraction)
(*) this is the simple and general way. You could also use the least common multiple to get cleaner results:
den = lcm(b,d)
a/b + c/d = (a * den/b) + c * den/d) / den
That way you would get 1/4 + 2/4 = 3/4 instead of 12/16
But computing the LCM is far beyond this answer...

Return value from constructed class

I'm trying to monkey with a class template that mimics the stl classes. I'm experimenting with a currency class as a new type to better handle currency in our system.
This is a very rough draft of my experiment:
template <class T> class CURRENCY
{
private:
int p_iDollars;
int p_iCents;
int p_iPrecision = pow(10, 5);
public:
CURRENCY(T dStartingValue)
{
int p = this->p_iPrecision;
double temp_dStartingValue = dStartingValue * p;
this->p_iDollars = temp_dStartingValue / p;
this->p_iCents = (dStartingValue - this->p_iDollars) * p;
}
CURRENCY operator+(T value)
{
this->p_iDollars = ((double) val()) + value;
}
CURRENCY operator-(T value)
{
this->p_iDollars = ((double) val()) - value;
}
CURRENCY operator*(T value)
{
this->p_iDollars = ((double) val()) * value;
}
CURRENCY operator/(T value)
{
this->p_iDollars = ((double) val()) / value;
}
CURRENCY operator= (int value)
{
this->p_iDollars = value;
}
double val()
{
return this->p_iDollars + ((double) this->p_iCents / this->p_iPrecision);
}
int dollars()
{
return this->p_iDollars;
}
int cents()
{
return this->p_iCents;
}
};
I want to be able to implement this class as a type like:
typedef CURRENCY<double> money;
int main()
{
money m = 3.141592653589;
m = m + 30; // added assignment operator here
cout << m << endl;
return 0;
}
I guess I'm not sure how to even word what I'm describing other than I want to return the current "value" of my object knowing that the object doesn't really have a value. I'm not sure how to allow my class to carry a default represented value that can be returned and manipulated.
In this case I would like cout << m << endl; to return my "new" value: 33.1416.
Any direction would be helpful because I'm just trying to wrap my head around this concept. Note: this code is super incomplete and not intended to be fully functional since I was experimenting but please feel free to correct any issues with logic or the direction I was going
I'm a dumbass and didn't include the assignment above...
First of all, the + and similar operators doesn't actually modify the object involved in the operation, which means you must create a new object that you then return from the operator function.
Something like
CURRENCY operator+(T value)
{
CURRENCY temp(*this);
temp.p_iDollars += value;
return temp;
}
template<typename T>
ostream& operator<<(ostream& lhs, const CURRENCY<T>& rhs) {
lhs << /*output rhs the way you want here*/;
}
Also it is very poor design to have operator+, operator/, etc modify the calling object. These should not be member functions and should not modify the calling object. Instead create a copy of the passed CURRENCY, modify that, and return it.

Operator overloading - does not match

I'm have a bit problem with operator overloading. I have two classes.
#include <iostream>
using namespace std;
class Meter; //Forward declaration
class Inch{
private:
double inches;
public:
Inch() : inches(0) {}
Inch(double i) { inches=i; }
friend Inch operator+ (const Meter& m, const Inch& i);
void out(){ cout << "Inch:" << inches << "\n"; }
double getInches() const { return inches; }
};
and
class Meter{
private:
double meter;
public:
Meter() : meter(0) {}
Meter(double m) { meter=m; }
Meter operator+ (const Inch& i) { return Meter(meter + i.getInches() * 0.0254); }
void out(){ cout << "Meter:" << meter; }
double getMeter() const { return meter; }
};
Inch operator+ (const Meter& m, const Inch& i)
{ return Inch(m.getMeter()/0.0254 + i.getInches()); }
In main I have one of each of these classes. I need to add them together with the order : m + i; So m must be the first object. In order to do that, I used friend function in order to use two objects as a parameter.
Inch i(6.4), resultInch;
Meter m(14), resultMeter;
i.out();
m.out();
resultMeter = m + i;
resultMeter.out();
resultInch = m + i;
resultInch.out();
With the above, resultMeter holds the correct value, but when I put resultInch compiler gives the "error no match for bla bla bla".
What am I missing?
The problem is that both these two operators are overloads for the exact same + in code. You can either use one or another, but not both in the same program.
Inch operator+ (const Meter& m, const Inch& i);
class Meter{
Meter operator+ (const Inch& i);
};
Consider what would happen if you had one Meter m; and Inch i; and you try to add them with m + i, which operator implementation should be called?
C++ cannot overload on return value. So when you want to be able to say:
meters = meters + inches;
and
inches = meters + inches;
both meters + inches are the same function. I second the recommendation to write one length class with a units attribute and conversion functions. But lacking that, I recommend you write conversion operators between your two length classes. Then only one addition function is needed (you should still write two: meters + meters and inches + inches) and the types can be converted back and forth.
Remove operator+ from both classes. Create proxy class which will be used as the result of addition:
class ProxyMeterInch
{
private:
double op1, op2;
public:
friend ProxyMeterInch operator+(Meter m, Inch i)
{
ProxyMeterInch r;
r.op1 = m.getMeter();
r.op2 = i.getInch() * 0.0254; // I tend to keep it in meters as I am European
return(r);
}
operator Meter() const
{
return(op1 + op2);
}
operator Inch() const
{
return((op1 + op2) / 0.0254);
}
};
You get the idea. Depending on the type you are trying to assign to correct conversion operator will be selected.
Ok, so I assume it's
Inch resultInch = m + i; // not Meter resultInch (...)
It is equivalent to:
Inch resultInch = (Meter)m.operator+(i);
and you have no way of converting between Meter and Inch.
Try changing it to Inch resultInch = i + m;.