I try to understand how this line of code in blow c++ program, and my questions are
return Rational(_n * rhs._d, _d * rhs._n);
how the _n refer to the first object data member?
how the temporary object refer get the a._n?
C++ program:
#include <iostream>
class Rational {
int _n;
int _d;
public:
Rational ( int numerator = 0, int denominator = 1 ) : _n(numerator), _d(denominator) {};
Rational ( const Rational & rhs ) : _n(rhs._n), _d(rhs._d) {}; // copy constructor
inline int numerator() const { return _n; };
inline int denominator() const { return _d; };
Rational operator / ( const Rational & ) const;
};
Rational Rational::operator / ( const Rational & rhs ) const {
return Rational(_n * rhs._d, _d * rhs._n);
}
// useful for std::cout
std::ostream & operator << (std::ostream & o, const Rational & r) {
return o << r.numerator() << '/' << r.denominator();
}
int main( int argc, char ** argv ) {
using namespace std;
Rational a = 7; // 7/1
Rational b(5, 3); // 5/3
cout <<"a is : " <<a << endl;
cout << " b is : "<< b << endl;
cout << " a/b is: "<< a / b << endl;
return 0;
}
which has out put of
a is : 7/1
b is : 5/3
a/b is: 21/5
this program is simple version of this program in github
To put it in a few words, the operator / can be written like this:
class Rational
{
//...rest of the stuff:
Rational Divide( const Rational & rhs) const
{
return Rational(_n * rhs._d, _d * rhs._n);
}
};
and instead of the operator / for result = a/b you can write result = a.Divide(b)
Basically operator / behaves the same way as Divide method:
Now , let's analyze the divide method:
you have:
result = a.Divide(b); // which is the same as result = a/b in your case
and
Rational Divide( const Rational & rhs) const
{
return Rational(_n * rhs._d, _d * rhs._n);
}
rhs is the argument passed to Divide which is the variable b.
_n and _d are the members of the variable a. You can also write them like this: this->_n and this->_d. Divide is a member function so it can access _n and _d directly.
Now to simplify this even further to understand the way it works, here is another way to write this:
class Radional {/*stuff*/};
Rational Divide( const Rational & a, const Rational & b)
{
return Rational(a._n * b._d, a._d * b._n);
}
For this example the result = a.Divide(b) transforms into result = Divide(a,b)
Notice that now you have a._n and a._d which is the first argument of function Divide
As a conclusion the expression a/b is just a very nice way of writing Divide(a,b) that c++ standard allows.
Related
Learning C++ right now and ran into a bit of a problem. While trying to complete an example and make sure it works ran into the error:
error: no match for 'operator<<' (operand types are 'std::istream' and 'const int') and Complex . Here is my code.
#include<iostream>
using namespace std;
class Complex {
private:
int real, imag;
public:
Complex(int r = 0, int i =0) {real = r; imag = i;}
// This is automatically called when '+' is used with
// between two Complex objects
Complex operator + (Complex const &obj) {
Complex res;
res.real = real + obj.real;
res.imag = imag + obj.imag;
return res;
}
int getR() const { return real; }
int getC() const { return imag ; }
ostream& aff(ostream& out)
{
out << real << " + i" << imag ;
return out ;
}
void print() { cout << real << " + i" << imag << endl; }
};
Complex operator + (const Complex & a , const Complex &b )
{
int r = a.getR() + b.getR();
int c = a.getC() + b.getC();
Complex x(r , c);
return x ;
}
ostream& operator<<(ostream& out , Complex& c)
{
return c.aff(out) ;
}
int main()
{
Complex c1(10, 5), c2(2, 4);
cout << c1 + c2 << endl ; // An example call to "operator+"
}
Not sure what is wrong with my code, can anyone help?
operator + returns by-value, that means what it returns is a temporary, it can't be bound to lvalue-reference to non-const (i.e. Complex&), which is the parameter type of operator<<.
You can change the parameter type to const Complex&,
ostream& operator<<(ostream& out , const Complex& c)
// ~~~~~
{
return c.aff(out) ;
}
and you have to make aff a const member function, to make it possible to be called on a const object.
ostream& aff(ostream& out) const
// ~~~~~
{
out << real << " + i" << imag ;
return out ;
}
Your function is waiting for a lvalue reference, and you try to print c1 + c2 that is a temporary.
You can bind a temporary to a const lvalue reference, so you must wait for a const Complex &c
ostream& operator<<(ostream& out , const Complex& c)
'operator>>' (operand types are 'std::basic_istream::__istream_type {aka std::basic_istream}' and '')
This error occurs due to use of endl
So omit use of endl in your code instead replace with '\n' whenever needed.
For example use:
cout<<"hello\n";
Instead of using:
cout<<"hello"<<endl;
I am trying to make a program that can opearate with complex numbers. However i got stuck with operator * I cannot figure out how to make these 2 cases work:
First:
c = 10 * d;
cout << c << endl;
Second:
c = d * 10;
cout << c << endl;
This is my header:
class Complex
{
private:
double Real, Imag;
public:
Complex() : Real(), Imag()
{
}
//----------------------------------------------------------------------
Complex (double Real) //Initialization with only one variable
{
this->Real = Real;
Imag = 0;
}
//----------------------------------------------------------------------
Complex (double Real, double Imag) //Complete initialization
{
this->Real = Real;
this->Imag = Imag;
}
//----------------------------------------------------------------------
Complex & operator = (const Complex &s)
{
Real = s.Real;
Imag = s.Imag;
return *this;
}
//----------------------------------------------------------------------
Complex operator * (Complex s) // (r + i) * x
{
this->Real *= s.Real;
this->Imag *= s.Real;
return *this;
}
//----------------------------------------------------------------------
Complex & operator *= (Complex s) //Reference
{
Real *= s.Real;
Imag *= s.Imag;
return *this;
}
//----------------------------------------------------------------------
friend Complex operator * (Complex s1, Complex s2);
//----------------------------------------------------------------------
friend ostream &operator << (ostream &s, const Complex &c)
{
s << c.Real << " + " << c.Imag;
return s;
}
};
//Out of class functions
inline Complex operator * (Complex s1, Complex s2) // x * (r + i)
{
s2.Real *= s1.Real;
s2.Imag *= s1.Real;
return s2;
}
//----------------------------------------------------------------------
bool Complex::operator == (const Complex &s) const
{
return (this->Real == s.Real && this->Imag == s.Imag);
}
//----------------------------------------------------------------------
#endif /* __Complex_H__ */
My idea was to use operator inside class for second case, and outside for first case. But I got error:
error: ambiguous overload for 'operator*' in 'd * 10
How to make it clear to compiler which overload to use?
My main is:
#include <iostream>
#include "complex.h"
using namespace std;
int main()
{
Complex c, d(3, 5);
c = 10 * d;
cout << c << endl;
c = d * 10;
cout << c << endl;
}
In the first case, the friend non-class method is invoked without ambiguity because first parameter is not a Complex but can be built as such using the double to Complex constructor
In the second case, member method * and friend function can be applied, hence the error.
There's no need for a friend operator using 2 Complex objects. It's only useful when first parameter is a non-class object / a class object where you cannot set/change the behaviour of *
You'd be better off with:
friend Complex operator * (double s1, const Complex &s2);
Notes:
standard library has a very good std::complex implementation.
it would be better to use constant references rather than value parameter passing
overloading member operator*(double s1) would be interesting to avoid converting to a Complex when you want to multiply by a real value.
I'm curently learning about operator overloading and I found this example:
#include <iostream>
using namespace std;
class MinMax
{
private:
int m_nMin; // The min value seen so far
int m_nMax; // The max value seen so far
public:
MinMax(int nMin, int nMax)
{
m_nMin = nMin;
m_nMax = nMax;
}
int GetMin() { return m_nMin; }
int GetMax() { return m_nMax; }
friend MinMax operator+(const MinMax &cM1, const MinMax &cM2);
friend MinMax operator+(const MinMax &cM, int nValue);
friend MinMax operator+(int nValue, const MinMax &cM);
};
MinMax operator+(const MinMax &cM1, const MinMax &cM2)
{
// Get the minimum value seen in cM1 and cM2
int nMin = cM1.m_nMin < cM2.m_nMin ? cM1.m_nMin : cM2.m_nMin;
// Get the maximum value seen in cM1 and cM2
int nMax = cM1.m_nMax > cM2.m_nMax ? cM1.m_nMax : cM2.m_nMax;
return MinMax(nMin, nMax);
}
MinMax operator+(const MinMax &cM, int nValue)
{
// Get the minimum value seen in cM and nValue
int nMin = cM.m_nMin < nValue ? cM.m_nMin : nValue;
// Get the maximum value seen in cM and nValue
int nMax = cM.m_nMax > nValue ? cM.m_nMax : nValue;
return MinMax(nMin, nMax);
}
MinMax operator+(int nValue, const MinMax &cM)
{
// call operator+(MinMax, nValue)
return (cM + nValue);
}
int main()
{
MinMax cM1(10, 15);
MinMax cM2(8, 11);
MinMax cM3(3, 12);
MinMax cMFinal = cM1 + cM2 + 5 + 8 + cM3 + 16;
cout << "Result: (" << cMFinal.GetMin() << ", " <<
cMFinal.GetMax() << ")" << endl;
return 0;
}
I don't understand how does the line MinMax cMFinal = cM1 + cM2 + 5 + 8 + cM3 + 16; work.
When this is calculated it becomes MinMax cMFinal = MinMax(3, 16). What happenes next? How does the compiler assign one object to another when I didn't define overloading assigment operator?
Lets say you have two MinMax objects, a and b. Then when you have a line like
MinMax c = a + b;
Then the compiler translates it to the following
MinMax c = operator+(a, b);
In other words, it's like a normal function call.
If you do multiple operations, like
MinMax d = a + b + c;
then the compiler will internally generate temporary variables and use, like
MinMax compilerGeneratedTemporary = operator+(a, b);
MinMax d = operator+(compilerGeneratedTemporary, c);
If it's the initialization you're wondering about, then it's calling the MinMax copy-constructor. When you declare and initialize an object variable at the same time then it's not an assignment, it just reuses the assignment operator.
The operator+ functions return a MinMax object, which is passed to the class copy-constructor.
If a class doesn't have a copy-constructor, the compiler will generate one for you automatically (with a few exceptions, see the reference linked below).
Read more about the copy-constructor here.
So I am working on "TEMPLATES" and I'm required to make a 3 attempt of a function called PrintMax -it's obvious what it does-, to print the maximum element in an array of 3 elements, each attempt is for a different data type in this array -double/int/complex-. So I'm required to first, create the class Complex, and its required operator overloads, after that I use the PrintMax function as template function to work on the 3 types of arrays.
The problem here lies within the 3rd array of course, I can't write the elements of Complex into the array in this for ( a + bi ), because this is my class Complex :
class Complex
{
private :
int imaginary;
int real;
public:
Complex (int = 0, int = 0);
~Complex ();
int getImaginary();
int getReal();
void setImagniary(int i);
void setReal (int r);
bool operator > (Complex&);
};
You can notice, I overloaded operator > to check, but I also have a little problem besides not being able to write the elements in that way, the second problem is I can't -or sleepy and my brain is dying- calculate which is maximum in this array of Complex numbers :
// Input: Complex Array
// 1+3i, 2+4i, 3+3i
// Expected Output: 2+4i
So I want to assign them in the array with this form : Arr[3] = {1+3i, 2+4i, 3+3i};
Why is that the expected output, why not 3+3i ?
Thanks for reading ~
It seems to me that you are looking for something like:
template <typename T> void PrintMax(T array[])
{
// It is assumed that array has 3 elements in it.
std::cout <<
array[0] > array[1] ?
(array[0] > array[2] ? array[0] : array[2]) :
(array[1] > array[2] ? array[1] : array[2])
std::endl;
}
You could use something like the following. Note that there are no range checks in the code, it is just to demonstrate a way how you could solve your problem.
Plus i would suggest you to use a container (eg. std::vector) instead of plain arrays.
#include <algorithm>
#include <cmath>
#include <iostream>
class Complex {
private:
int imaginary;
int real;
public:
Complex(int r, int i) :
imaginary(i), real(r) {
}
~Complex() {
}
int getImaginary() const {
return imaginary;
}
int getReal() const {
return real;
}
void setImaginary(int i) {
imaginary = i;
}
void setReal(int r) {
real = r;
}
double getAbsolut() const {
return std::abs(std::sqrt(std::pow(imaginary, 2) + std::pow(real, 2)));
}
friend bool operator<(const Complex& lhs, const Complex& rhs);
friend std::ostream& operator<<(std::ostream& stream,
const Complex& complex);
};
bool operator<(const Complex& lhs, const Complex& rhs) {
return lhs.getAbsolut() < rhs.getAbsolut();
}
std::ostream& operator<<(std::ostream& stream, const Complex& complex) {
stream << "Complex(" << complex.real << "+" << complex.imaginary
<< "i)";
return stream;
}
template<int size, class T>
void getMax(const T arr[]) {
T max_value = arr[0];
for (size_t i = 1; i < size; ++i) {
max_value = std::max(max_value, arr[i]);
}
std::cout << "max: " << max_value << std::endl;
}
int main(int argc, char **argv) {
Complex arr_complex[] = { Complex(3, 3), Complex(2, 4), Complex(1, 3) };
int arr_int[] = { 3, 5, 1 };
double arr_double[] = { 2.3, 5.6, 9.1 };
getMax<3>(arr_complex);
getMax<3>(arr_int);
getMax<3>(arr_double);
return 0;
}
I am trying to create a function that conjugate a complex number
for example A(2, 3) will turn into A(2,-3) by typing ~A
i have done a little code below but i guess it's wrong, i hope you can help me slove this.
i have quoted the part that i did wrong in the code below.
#include <iostream>
using namespace std;
class Complex
{
private:
double real;
double imaginenary;
public:
Complex();
Complex(double r, double i = 0);
// Declaration
Complex operator~(const Complex & c) const;
Complex operator+(const Complex & c) const;
Complex operator-(const Complex & c) const;
Complex operator*(const Complex & c) const;
Complex operator*(double n) const;
friend Complex operator*(double m, const Complex & c)
{ return c * m; }
friend ostream & operator<<(ostream & os, const Complex & c);
};
Complex::Complex()
{
real = imaginenary = 0;
}
Complex::Complex(double r, double i )
{
real = r;
imaginenary = i;
}
// Definition
Complex Complex::operator~(const Complex & c) const
{
Complex conj;
conj.imaginenary = -1 * imaginenary;
conj.real = real;
}
Complex Complex::operator+(const Complex & c) const
{
Complex sum;
sum.imaginenary = imaginenary + c.imaginenary;
sum.real = real + c.real;
return sum;
}
Complex Complex::operator-(const Complex & c) const
{
Complex diff;
diff.imaginenary = imaginenary - c.imaginenary;
diff.real = real - c.real;
return diff;
}
Complex Complex::operator*(const Complex & c) const
{
Complex mult;
mult.imaginenary = imaginenary * c.imaginenary;
mult.real = real * c.real;
return mult;
}
Complex Complex::operator*(double mult) const
{
Complex result;
result.real = real * mult;
result.imaginenary = imaginenary * mult;
return result;
}
ostream & operator<<(ostream & os, const Complex & c)
{
os << "(" << c.real <<"," << c.imaginenary<<"i)";
return os;
}
int main()
{
Complex A;
Complex B(5, 40);
Complex C(2, 55);
cout << "A, B, and C:\n";
cout << A <<"; " << B << ": " << C << endl;
cout << " complex conjugate is" << ~C << endl;
cout << "B + C: " << B+C << endl;
cout << "B * C: " << B*C << endl;
cout << "10 * B: " << 10*B << endl;
cout << "B - C: " << B - C << endl;
return 0;
}
The tilde (~) operator is a unary operator so it shouldn't accept a parameter (it works on *this). You also forgot to return a value from operator~.
Complex operator~() const
{
return Complex( real, -1 * imaginenary);
}
See your fixed code here
BTW: It's spelt imaginary.
try
Complex Complex::operator~() const
{
Complex conj;
conj.imaginenary = -1 * imaginenary;
conj.real = real;
return conj;
}
But it might be wiser to remove the operators from the class definition and create (friend) functions instead. It works better with implicit type conversion.
Lots of code, but if you would have compared your operator~ to e.g. operator+ , you would have spotted one detail - there's no return statement.
Complex Complex::operator~(const Complex & c) const
{
Complex conj;
conj.imaginenary = -1 * c.imaginenary;
conj.real = c.real;
return conj;
}
This should do.
Although it's not the best idea to return anything you've allocated inside nonglobal scope, since that region in the memory can be overwritten anytime. And btw it's imaginary, not imaginenary :)
friend Complex operator*(double m, const Complex & c) { return c * m; }
friend ostream & operator<<(ostream & os, const Complex & c);
Is there anyway to avoid using friend in this problem? because i have read that from the book but not quite understand it.