Invalid conversion error when overloading ostream& operator<< - c++

Here is the prototype of my class Rational
#ifndef RATIONAL_H
#define RATIONAL_H
//forward declaration
class ostream;
class Rational
{
int numerator,denominator;
public:
// the various constructors
Rational();
Rational(int);
Rational(int,int);
//member functions
int get_numerator()const{return numerator;}
int get_denominator()const{return denominator;}
// overloaded operators
// relational operators
bool operator==(const Rational&)const;
bool operator<(const Rational&)const;
bool operator<=(const Rational&)const;
bool operator>(const Rational&)const;
bool operator>=(const Rational&)const;
//arithmetic operators
Rational operator+(const Rational&)const;
Rational operator-(const Rational&)const;
Rational operator*(const Rational&)const;
Rational operator/(const Rational&)const;
//output operator
friend ostream& operator<<(ostream&, const Rational&);
};
#endif //RATIONAL_H
And this is the implementation of the overloaded output operator<< in rational.cpp
// friend output operator
ostream& operator<<(ostream& os, const Rational& r)
{
os<<r.get_numerator()<<"/"<<r.get_denominator();
}
When I try to compile I get the following error
g++ -c rational.cpp
rational.cpp: In function ‘ostream& operator<<(ostream&, const Rational&)’:
rational.cpp:81:26: error: invalid conversion from ‘const char*’ to ‘int’ [-fpermissive]
rational.cpp:7:1: error: initializing argument 1 of ‘Rational::Rational(int)’ [-fpermissive]
I wanted to be able to display the rational number as numerator/denominator when it is passed to the << operator.

Your first issue is that you try to forward declare ostream as a class. Assuming that you mean to use std::ostream, you can't do that, its not legal.
For one, it's a typedef for a template specialization, not a class itself.
Second, because you don't #include <ostream> you don't have a definition for any of the standard << overloads for ostream so when you try to << a string literal, the compiler trys to convert the string literal to a Rational type as that is the only type that has a << overload visible.
Simply, you need to #include <ostream> and qualify ostream with std:: where you use it.
A third point is that your overload of operator<< needs to return something. You should either append a return os; statement or simply return the whole streaming expression.

Although I am not sure why you get such error message, I do found an error: you should add:
return os;
in your friend function.

Related

Problem with overloading input operator in c++

I started to learn C++ recently and i ran into this trouble with using overloaded input operator >>.
I am writing a class to describe a Complex number.
My problem is: If i put my main() in the Complex.cpp, my program run normally. But if i create a new file main.cpp and put my main() there i ran into error.
error: invalid operands to binary expression ('std::istream' (aka 'basic_istream') and 'Complex')
candidate function not viable: no known conversion from 'std::istream' (aka 'basic_istream') to 'std::istream *' (aka 'basic_istream *') for 1st argument; take the address of the argument with &
(There are a lots more error bellow but they point to istream so i don't think that is the problem)
This is my header file:
#include <iostream>
using namespace std;
#ifndef HEADER_H
#define HEADER_H
#endif // HEADER_H
class Complex
{
public:
double _real;
double _imag;
public:
Complex(double, double);
double getReal() const;
double getImag() const;
void setReal(double);
public:
Complex operator=(const Complex&);
Complex * operator+(const Complex&);
Complex * operator+(const double&);
friend Complex * operator+(const double&, const Complex&);
Complex * operator++();
Complex * operator++(int);
Complex * operator--();
Complex * operator--(int);
operator double() const;
friend ostream &operator<<(ostream*, const Complex&);
friend istream &operator>>(istream*, Complex&);
};
And i created Complex.cpp to identify the function:
#include "Complex.h"
using namespace std;
Complex::Complex(double a, double b)
{
this->_real = a;
this->_imag = b;
}
double Complex::getReal() const{...}
void Complex::setReal(double x){...}
double Complex::getImag() const{...}
Complex Complex::operator=(const Complex& other){...}
Complex * Complex::operator+(const Complex& other){...}
Complex * Complex::operator+(const double &other){...}
Complex * operator+(const double &first, const Complex &second){...}
Complex * Complex::operator++(){...}
Complex * Complex::operator++(int){...}
Complex * Complex::operator--(){...}
Complex * Complex::operator--(int){...}
Complex::operator double() const{...}
ostream &operator<<(ostream &output, const Complex &comp)
{
output << comp._real << " + " << comp._imag << "i";
return output;
}
istream &operator>>(istream &input, Complex &comp)
{
input >> comp._real >> comp._imag;
return input;
}
This is my main:
#include "Complex.h"
int main()
{
Complex com4(0,0);
cout << "Input Complex: ";
cin >> com4;
cout << com4 <<endl;
}
You declared io operators with pointers (which is wrong)
friend ostream &operator<<(ostream*, const Complex&);
friend istream &operator>>(istream*, Complex&);
but implemented it correctly with references.
friend ostream &operator<<(ostream&, const Complex&) {...}
friend istream &operator>>(istream&, Complex&) {...}
When you have your main() in Complex.cpp, the compiler can see those correct implementations (that are not defined in any header).
If you have your main() somewhere else, the compiler can only see the declarations in the header, which have the wrong signature.
Solution will be to fix the declarations of operator<< and operator>> in the header, so that they match the implementation.
As a note and as already mentioned in the comments: Your other operator-overloads should return Complex & or Complex not Complex *. Take a look at std::complex or this page, detailing operator overloading to see what the canoncial implementations look like.

How to output multiplied user created class c++

I am working on an assignment overloading operators for a user-created class of rational numbers but can not output two "Rational" objects in the same line. For example:
std::cout<<5*10<<std::endl;
Outputs 50 just fine. However when I try to do,
std::cout<<Rational_1*Rational_2<<std::endl;
I receive an error. If I instead assign the value to a third rational such as
Rational_3=Rational_1*Rational_2;
std::cout<<Rational_3<<std::endl;
Then the program outputs just fine. I have brought this up to my professor but even he does not know how to fix it. Any explanation as to why this is happening would be helpful. I would like to know why this is an issue instead of just simply getting a piece of code that works.
#include <iostream>
using namespace std;
class Rational{
public:
Rational();
Rational(int whole_number);
Rational(int numerator_input,int denominator_input);
friend Rational operator *(Rational rat_1, Rational rat_2);
` friend ostream& operator <<(ostream& out,Rational& output);
void simplify();
private:
int numerator,denominator;
};
int main(){
Rational r1(2,3),r2(3,4),r3;
r3=r1*r2;
cout<<r3<<endl;
//cout<<r1*r2<<endl;
return 0;
}
Rational::Rational(){
numerator=0;
denominator=1;
}
Rational::Rational(int whole_number){
numerator=whole_number;
denominator=1;
}
Rational::Rational(int numerator_input,int denominator_input){
numerator=numerator_input;
if(denominator_input==0){
cout<<"A rational number can not have a 0 in the denominator\n";
exit (5);
}
denominator=denominator_input;
simplify();
}
ostream& operator <<(ostream& out,Rational& output){
out<<output.numerator<<"/"<<output.denominator;
return out;
}
Rational operator *(Rational rat_1, Rational rat_2){
Rational rat_3;
rat_1.simplify();
rat_2.simplify();
rat_3.numerator=rat_1.numerator*rat_2.numerator;
rat_3.denominator=rat_1.denominator*rat_2.denominator;
rat_3.simplify();
return rat_3;
}
void Rational::simplify(){
//Flip negative sign to numerator
for(int counter=1000000;counter>0;counter--){
if((numerator%counter==0)&&(denominator%counter==0))
{
numerator=numerator/counter;
denominator=denominator/counter;
}
}
}
The difference between the operator<< that takes an int as in your first snippet is that it takes it's argument by value.
Your overloaded operator<< takes a Rational object by reference and Rational_1*Rational_2 returns an temporary object, temporary objects are not allowed to bind to non-const references.
Either take your argument by value or by const& to fix this:
friend ostream& operator <<(ostream& out, const Rational& output);
Or
friend ostream& operator <<(ostream& out, Rational output);
Declare the operator like
friend ostream& operator <<(ostream& out, const Rational& output);
^^^^^
You may not bind a temporary object to a non-constant lvalue reference.

header file for rational class : no type error

I have built a rational class, here is my .h file:
#ifndef RATIONAL_H
#define RATIONAL_H
#include <iostream>
using std::istream;
using std::ostream;
class Rational
{
public:
Rational();
Rational(int n);
Rational(int n, int d);
Rational(const Rational& other);
~Rational();
Rational operator+(const Rational& other);
Rational operator-(const Rational& other);
Rational operator*(const Rational& other);
Rational operator/(const Rational& other);
Rational operator+(int n);
Rational operator-(int n);
Rational operator*(int n);
Rational operator/(int n);
Rational& operator=(const Rational& other);
bool operator==(const Rational& other);
bool operator!=(const Rational& other);
bool operator>=(const Rational& other);
bool operator<=(const Rational& other);
bool operator<(const Rational& other);
bool operator>(const Rational& other);
bool operator==(int n);
bool operator!=(int n);
bool operator>=(int n);
bool operator<=(int n);
bool operator<(int n);
bool operator>(int n);
friend istream& operator>>(istream& is, Rational &r);
friend ostream& operator<<(ostream& is, Rational &r);
private:
int
num,
den;
};
#endif // RATIONAL_H
I am getting multiple errors, my main being:
include\Rational.h|8|error: ISO C++ forbids declaration of 'Rations'
with no type [-fpermissive]|
include\Rational.h|41|error: 'istream' does not name a type|
include\Rational.h|42|error: 'ostream' does not name a type|
and the rest in my main file (which are all cause because I tried to use >> and <<). I have searched for hours now, found similar problems, tried multiple solutions I don't want to shoot in the dark, I want to know what the problem is and why. For the record here is what I have for Rations in my implementation file:
Rational::Rations(int n)
{
num = n;
den = 1;
}
Let me know if my complete cpp implementation file or main is needed to solve this.. Also, I am using codeblocks, I have added include into my compiler in build options.
You seem to intend that Rations(int) should be a constructor for you class, but the name of the constructor must be the same as the name of the class:
Rational::Rational(int n)
If it was not a typo then I have no idea why you changed Rational to Rations.
As for istream and ostream, your class refers to them, but you haven't declared them-- the compiler has no idea what you're talking about. You must either include the proper headers in your header file (above the class definition):
#include <istream>
using std::istream;
using std::ostream;
or, if you're going to be really strict about it, use forward declaration above the class definition:
class istream;
class ostream;
and then put the #include directives in your source code, above the function definitions.
Constructors have the same name as the class and have no return type.
Your function Rations is spelled differently and either needs a return type of void (not returning a value) or it needs to return a value.

C++ error with operator overloading

I am trying to make program that uses operator overloading to do basic math operations on rational numbers. I keep getting an errors in the functions where it says i must have an arithmetic of enum type. Also I get an error istream where it says that the numerator and denominator are undefined.
Here is the header file:
#ifndef rational_H
#define rational_H
#include <iostream>
using namespace std;
class Rational
{
friend ostream & operator<<(ostream & , const Rational &);
friend istream & operator<<(istream & , const Rational &);
public:
// default constructor
Rational(int = 0, int = 1);
// overload operators for "normal" operation
Rational operator+(const Rational&);
Rational operator-(const Rational&);
Rational operator*(const Rational&);
Rational operator/(const Rational&);
operator double();
// overload relational operators for "normal" operation
bool operator>(const Rational&) const;
bool operator<(const Rational&) const;
bool operator>=(const Rational&) const;
bool operator<=(const Rational&) const;
bool operator==(const Rational&) const;
bool operator!=(const Rational&) const;
protected:
int *numerator;
int *denominator;
void reduction(void);
};
#endif
// this part of code is from my rational cpp file//
// default constructor//
Rational::Rational( int n, int d )
{
*numerator =1 ;
// sets numerator
if(d == 0)
d = 1; // If denominator is zero then set to one.
*denominator = 0;
// sets denominator
reduction(); // store the fraction in reduced form
}
// all the other operators have the same error as well//
Rational Rational::operator-(const Rational&a)
{
Rational sub;
sub.numerator = *this->numerator * a.denominator -//the error is with the 'a'needs to be an arithmetic type or enum type//
*this->denominator * a.numerator;
sub.denominator = *denominator * a.denominator;
sub.reduction();
return sub;
}
//also the istream part has an error where the denominator and numerator is underfined as well//
istream& operator >> ( istream& inputStream, Rational& rnum )
{
inputStream>>rnum.*numerator;//numerator and denmoinator undefined for some reason//
inputStream.ignore(1);
inputStream>>rnum.*denominator;
return inputStream;
}
There are multiples small errors in your code.
First of all you should not be using pointers for these members, it does not bring any advantages.
But as you chose this way, you have to dereference them each time you want to read or update them, which hasn't be done in your operator- implementation, and incorrectly in your operator>> implementation (the asterisk needs to be put before the whole expression).
Next error in the code you provided, you marked as friend operator<<(istream & , const Rational &) in your class definition, but it should have been operator>>. And this declaration needs to match the definition that appears next (i.e., remove the const of the second argument, which obviously has to be mutated).
And, last but not least, the undefined behavior caused by all the dereferencing of you uninitialized pointers…
This is probably a copy and past error. The line
friend istream & operator<<(istream & , const Rational &);
should be
friend istream & operator>>(istream & , Rational &);
Your implementation later on in the file has:
istream& operator >> ( istream& inputStream, Rational& rnum )
{
...
}
It matches the second declaration, not the first one.

C++ friend operator+ overloading

I'm confused about friend operator overloading. It has no problem if I write the friend operator overloading function within the header file, but it gives me the following errors once I moved the function to class file. I googled some samples and they all written the function in the header file. What did I do wrong? Thanks.
...: error: expected ‘,’ or ‘...’ before ‘&’ token
...: error: ISO C++ forbids declaration of ‘statisticain’ with no type
...: error: ‘main_savitch_2C::statistician operator+(int)’ must have an argument of class or enumerated type
// a.h
class A
{
public:
friend A operator + (const A &a1, const A &a2);
};
// a.cpp
#include "a.h"
A operator + (const A &a1, const A &a2)
{
//
}
From the error message you're getting:
ISO C++ forbids declaration of ‘statisticain’ with no type
I think that you misspelled "statistician" by reversing the last two letters (note that you have "statisticain" instead of "statistician.")
This should have nothing to do with whether operator+ is implemented in the header or the .cpp file.
I agree with the previous answer. Also, if I may ask, why make the function a friend when both arguments and the return type are of the same class? why not make it a member so the first argument is passed implicitly by the this operator?
Move the two param version out of the class declaration. Or just use one param and the this pointer.
Here's an abbreviated real world example.
//complexnumber.h
class ComplexNumber
{
float _r;
float _i;
friend ComplexNumber operator+(const ComplexNumber&, const ComplexNumber&);
public:
ComplexNumber(float real, float img):_r(real),_i(img) {}
ComplexNumber& operator + (const ComplexNumber &other);
};
ComplexNumber operator+(const ComplexNumber &c1, const ComplexNumber& c2);
//complexnumber.h
ComplexNumber operator+(const ComplexNumber &c1, const ComplexNumber& c2)
{
return ComplexNumber(c1._r+c2._r, c1._i+c2._i);
}
// static
ComplexNumber& ComplexNumber::operator + (const ComplexNumber &other)
{
this->_r = this->_r + other._r;
this->_i = this->_i + other._i;
return *this;
}