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.
Related
I'm doing a tutorial on C++ to really dig into the nitty-gritty of it, because frankly it's an awesome and powerful language. I'm still fairly new at it though, and I'm having issues with my operator overloading for the ostream operator.
Since this is a tutorial I'm trying to keep my code as organized and modular as possible to avoid confusion. There are 3 layers to my code:
main.cpp - runs the Exercises.
Exercises.cpp/Exercises.h - contains static functions for the exercises.
ComplexNumber.cpp/ComplexNumber.h - represents a complex number object in line with the tutorial.
Main is fairly simple: set of calls to Exercises::ExerciseName().
Exercises.cpp:
#include "Exercises.h"
void Exercises::ComplexNumberClass() {
ComplexNumber c; /** Runs the blank constructor */
ComplexNumber c1(2, 3); /** Runs the args-filled constructor */
ComplexNumber c2 = c1; /** Runs the copy constructor */
c = c2;
cout << c1 << endl;
}
The header file only has the header for that function as a public static void function, i.e. callable and executable. The ComplexNumber files are where I think the problem is (please correct me if I'm wrong):
ComplexNumber.cpp (without constructors and accessors):
#include "ComplexNumber.h"
using namespace ComplexNumbers;
using namespace std;
ostream& operator<< (ostream& out, ComplexNumber& num){
out << "(" << num.GetReal() << ", " << num.GetImaginary() << ")";
return out;
}
const ComplexNumber &ComplexNumber::operator=(const ComplexNumber &num) {
cout << "Using assignment operator override" << endl;
real = num.real;
imaginary = num.imaginary;
return *this;
}
ComplexNumber.h:
#ifndef OPERATOROVERLOADING_COMPLEXNUMBER_H
#define OPERATOROVERLOADING_COMPLEXNUMBER_H
#include <iostream>
using namespace std;
namespace ComplexNumbers {
class ComplexNumber {
private:
double real;
double imaginary;
public:
ComplexNumber();
ComplexNumber(double real, double imaginary);
ComplexNumber(const ComplexNumber &num);
const ComplexNumber &operator=(const ComplexNumber &num);
double GetReal() const {
return real;
}
double GetImaginary() const {
return imaginary;
}
};
ostream &operator<<(ostream& out, ComplexNumber& num);
}
#endif //OPERATOROVERLOADING_COMPLEXNUMBER_H
When I build this, it's telling me that I have an "undefined reference to 'cave_of_programming::operator<<(std::ostream&, cave_of_programming::ComplexNumber&)'. The method headers match, and I'm building with Jetbrains CLion.
My research suggests that the problem is in the linker, but I've looked at my CMakeLists.txt and found that it is linking up all of the appropriate files.
SOURCE_FILES main.cpp Exercises.cpp Exercises.h ComplexNumbers/ComplexNumber.cpp ComplexNumbers/ComplexNumber.h
Does anybody have an idea as to why this isn't working? What am I missing?
The problem is that you defined ostream &operator<<(ostream& out, ComplexNumber& num) inside the class. This doesn't make much sense to the compiler because it knows to override the operator<< when it gets an ostream object and a class of some type,
but the way you implemented it, it gets the ostream, a ComplexNumber, and another ComplexNumber as the 'this' reference.
In order to correctly overload a binary operator you have two options:
Define the operator inside the class, and give it only the ostream as parameter
class ComplexNumber
{
...
ostream &operator<<(ostream& out) const;
};
Or define the operator outside the class and give it both the parameters:
class ComplexNumber
{
...
};
ostream &operator<<(ostream& out, const ComplexNumber& num);
Note that in the second implementation, you need to add the function as a friend of the class if you want to access any private members.
Also note, that it's a good idea to use const here like I put in the examples, otherwise you won't be able to use the operator on const ComplexNumbers.
This question already has answers here:
What are the basic rules and idioms for operator overloading?
(8 answers)
Closed 6 years ago.
I am getting error while trying to compile the following code. I am beginner. Please help me figuring it out. I am trying to overload the operators _,+,/,*. It shows error while compiling. Should I use "friend" to solve this?
#include<stdio.h>
class complex{
private:
double real; //real part of complex
double imag; // imaginary part of complex
public:
complex(double r=0., double i=0.):real(r),imag(i)
{
} // constructor with initialization
complex(const complex&c):real(c.real),imag(c.imag)
{
} // copy constructor with initialization
~complex()
{
} // destructor
double re() const
{
return real;
} // read real part
double im() const
{
return imag;
} // read imaginary part
const complex& operator=(const complex&c)
{
real=c.real;
imag=c.imag;
return *this;
} //assignment operator
const complex& operator+=(const complex&c)
{
real += c.real;
imag += c.imag;
return *this;
} // addition of current complex
const complex& operator-=(const complex&c)
{
real -= c.real;
imag -= c.imag;
return *this;
} // subtract from current complex
const complex& operator*=(const complex&c)
{
double keepreal = real;
real = real*c.real-imag*c.imag;
imag = keepreal*c.imag+imag*c.real;
return *this;
} // multiply current complex with a complex
const complex& operator/=(double d)
{
real /= d;
imag /= d;
return *this;
} // divide current complex with real
void print(const complex&c)
{
printf("(%f,%f)\n",c.re(),c.im() );
} // printing complex number
friend complex operator !(const complex& c)
{
return complex(c.re(),-c.im());
}
friend double abs2(const complex& c)
{
return c.re()*c.re()+c.im()*c.im();
} // absolute value of complex
const complex& operator/=(const complex&c)
{
return *this *= (!c)/=abs2(c);
} // divide the current complex by a complex
const complex operator-(const complex& c)
{
return complex(-c.re(),-c.im());
} // negative of complex number
const complex operator-(const complex& c,const complex& d)
{
return complex(c.re()-d.re(),c.im()-d.im());
} // difference between complex numbers
const complex operator+(const complex& c,const complex& d)
{
return complex(c.re()+d.re(),c.im()+d.im());
} // addition of complex numbers
const complex operator*(const complex& c,const complex& d)
{
return complex(c)*=d;
} // multiplication of complex numbers
const complex operator/(const complex& c,const complex& d)
{
return complex(c)/=d;
} // division of complex numbers
};
int main(){
complex c(1.,0.),d(3.,4.);
print(c-d);
print(c/d);
return 0;
}
the output I am getting is:
complex_nums.cpp:76:59: error: ‘const complex complex::operator-(const complex&, const complex&)’ must take either zero or one argument
const complex operator-(const complex& c,const complex& d)
^
complex_nums.cpp:80:59: error: ‘const complex complex::operator+(const complex&, const complex&)’ must take either zero or one argument
const complex operator+(const complex& c,const complex& d)
^
complex_nums.cpp:84:59: error: ‘const complex complex::operator*(const complex&, const complex&)’ must take either zero or one argument
const complex operator*(const complex& c,const complex& d)
^
complex_nums.cpp:88:59: error: ‘const complex complex::operator/(const complex&, const complex&)’ must take exactly one argument
const complex operator/(const complex& c,const complex& d)
^
complex_nums.cpp: In function ‘int main()’:
complex_nums.cpp:96:11: error: ‘print’ was not declared in this scope
print(c-d);
^
complex_nums.cpp:97:9: error: no match for ‘operator/’ (operand types are ‘complex’ and ‘complex’)
print(c/d);
All your operators (+,-,*,/) need exactly one or no arguments, unless they are friend functions. Mark all the operator functions as friend, and the code should work. Otherwise, eliminate 1 parameter from each of the operators, and instead of that use the current instance (this). Example for + operator with parameter removed:
const complex operator+(const complex& c)
{
return complex(c.re()+re(),c.im()+im());
}
Reference of friend arithmetic operators: http://www.learncpp.com/cpp-tutorial/92-overloading-the-arithmetic-operators-using-friend-functions/
Next Error
What are you doing with your print() function? It should be in global scope, because it takes a complex as parameter. Move print() out of the class into global scope, like this. If you still want to keep a print() for the object itself, do so, but the one for your class should look like below:
class complex
{
void print(const complex&c)
{
printf("(%f,%f)\n",re(),im() );
} // printing complex number
};
void print(const complex&c)
{
printf("(%f,%f)\n",c.re(),c.im() );
} // printing complex number
Binary operators are either free functions with 2 arguments (preferred) or member functions with one argument (not so good).
You have defined member functions with 2 arguments.
Turning them into free functions by adding friend is one way.
Another is to make them free functions, defined outside the class but written in terms of member functions (as you have done anyway):
struct complex
{
/* ... */
};
// class definition ends
//free function
inline complex operator/(const complex& c,const complex& d)
{
return complex(c)/=d;
} // division of complex numbers
Note, this function can be improved:
inline complex operator/(complex c,const complex& d)
{
c /= d;
return c;
}
Also, unary operators should return complex&, not const complex&. The thing you're returning is mutable, because you just mutated it.
For the errors with the operators must take either zero or one argument, this is because you are implementing the non-member function as a member funciton. These should be free functions to work properly, or should only take one argument and use this as the other.
See this question for clarification:
Operator overloading : member function vs. non-member function?
For the error with print, I guess you are trying to call the print member function. To do that you need to do e.g. the following:
complex(c-d).print();
I've been trying to overload the << (cout) and >> (cin) operators for awhile now for a class of complex numbers that I was given the prototypes for in a .h file to do.
This is my attempt to do so in the class.cpp file:
std::istream &operator>> (std::istream &in, complex& c) {
double h, j;
in >> h >> j;
c.set(h,j);
return in;
}
std::ostream &operator<<(std::ostream &out, complex c) {
out << c.getReal;
out << c.getImag;
return out;
}
This is really the first time I've seen the std:: istream and std:: ostream rather than cout and cin and i'm not really sure how cout << and cin >> are all related
I try testing it on the main.cpp file but i get errors
The >> should absorb a complex argument into the complex class argument and change the value of private members real and imag
Not sure if I'm supposed to use my set function here
This is the protype .h file filled I was given:
#ifndef COMPLEX_H
#define COMPLEX_H
class complex {
public:
complex();
complex(double a);
complex(double a, double b);
complex(int a, int b);
void print() const;
void set(double a = 0, double b = 0);
void set(int a = 0, int b = 0);
double getReal() const;
double getImag() const;
void get(double&, double&) const;
complex operator+ (double& x);
complex operator+ (complex&);
complex operator+= (complex&);
complex operator+= (int&);
complex operator++ (int);
complex operator++ ();
complex operator- (double&);
complex operator- (complex&);
complex operator-= (complex&);
complex operator-= (double&);
complex operator-- (int);
complex operator-- ();
complex operator* (complex&);
complex operator* (double&);
complex operator*= (complex&);
complex operator*= (double&);
complex operator/ (complex&);
complex operator/= (complex&);
complex operator/= (double);
complex operator/ (double);
void operator= (const complex&);
bool operator== (complex&);
bool operator!=(complex &c);
friend std::istream &operator>> (std::istream &in, complex& c);
friend std::ostream &operator<<(std::ostream &out, complex c);
/*complex conj() const;
double norm() const;
double modulus() const;
*/
private:
double real;
double imag;
};
#endif // COMPLEX_H
Can someone show me how to properly overload for this?
Ok so I'm now trying for output a + bi :
std::ostream& operator<< (std::ostream& out, complex const& c) {
return out << c.getReal() << "+" << c.getImag() << "i";
}
and for input:
std::istream& operator>> (std::istream& in, complex& c) {
double h, j;
if (in >> h >> "+" >> j >> "i") {
c.set(h, j);
}
return in;
}
However I get the following error when I compile:
This is for line 181 of my complex.cpp file(class complex implementation file) where if (in >> h >> "+" >> j >> "i") {is located of the above function definition is located:
binary '>>': no operator found which takes a right-hand operand of type 'const char [2]' (or there is no acceptable conversion)
the following are all for line 45(Note each error is separate,total of 7 for this line) of my complex.h file where friend std::istream &operator>> (std::istream &in, complex& c); protoype is located.
'istream':is not a member of 'std'
syntax error missing ';' before '&'
'istream':'friend' not permitted on data declarations
missing type specifier-int assumed. Note:C++ does not support default-int
unexpected token(s) preceding';'
namespace "std" has no member "istream"
namespace "std" has no member "istream"
the following are for line 46 of my complex.h file where
friend std::ostream &operator<<(std::ostream &out, complex c);
is located
'ostream': is not a member of 'std'
syntax error: missing ';' before '&'
'ostream':'friend' not permitted on data declarations
missing type specifier -int assumed.Note: C++ does not support default-int
unexpected token(s) preceding ';'
namespace "std" has no member "ostream"
namespace "std" has no member "ostream"
I noticed both are the same type of errors. Note I have
#include<iostream>
using namespace std;
both on the complex.cpp file and the main.cpp file
Let's start with the simple stuff: std::cin is an instance of a type derived from std::istream. Similarly, std::cout is an instance of a type derived from std::ostream. These stream types are used to have something you can overload the input and output operators for (and you should not try to derive from them to change their behavior - that's done using std::streambuf). There are other stream types, e.g., std::ifstream/std::ofstream (to read from/write to files) and std::istringstream/std::ostringstream (to read from/write to strings).
The next thing to look at is your output operator: for starters, you need parenthesis when calling a member function. You'll also need a separator between the two values as otherwise the real and the imaginary part may blend into each other. I'd probably implement the operator as
std::ostream& operator<< (std::ostream& out, complex const& value) {
return out << value.getReal() << " " << value.getImag();
}
The use of a space and no other delimiter may be suboptimal in general but makes reading easier. For an actual implementation of a complex class I might use a format writing real+imagi or (real,imag) but these are harder to parse.
Reading values from a stream should always be checked after an attempt to read a value was made. For example, the code could look like this:
std::istream& operator>> (std::istream& in, complex& c) {
double h, j;
if (in >> h >> j) {
c.set(h, j);
}
return in;
}
Except for the missing check the input function looks OK assuming the two values are separated by a space: before attempting to read a value, space is skipped by default with the input operators. If the values are formatted more fancy with some separators, these would need to be separately processed. The code to do so could look like the this:
template <char C>
std::istream& skip_char(std::istream& in) {
if ((in >> std::skipws).peek() != C) {
in.setstate(std::ios_base::failbit);
}
else {
in.ignore();
}
return in;
}
std::istream& (*const open_parenthesis)(std::istream&) = &skip_char<'('>;
std::istream& (*const close_parenthesis)(std::istream&) = &skip_char<')'>;
std::istream& (*const comma)(std::istream&) = &skip_char<','>;
std::istream& operator<< (std::istream& in, complex& c) {
double real, imag;
if (in >> open_parenthesis >> real >> comma >> imag >> close_parenthesis) {
c.set(real, imag);
}
return in;
}
These funny looking entities open_parenthesis, close_parenthesis, and comma are function pointers initialized to point to instance of the function template skip_char. They have a specific signature which qualifies them as being manipulators. When "reading into" a manipulator, the corresponding function is called with the stream they are "read" from. That is, for example std::cin >> comma results in a call comma(std::cin) which is actually a call to skip_char<','>(std::cin). However, I guess for this assignment the full-blown approach is a bit of overkill.
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.
I'm trying to overload the >> and << operators for use in a complex number class. For some reason my << and >> functions cannot access the real and imaginary parts of the complex objects even though I've made them friends of the class.
Complex.h:
#ifndef COMPLEX_H
#define COMPLEX_H
class Complex
{
friend std::ostream &operator<<(std::ostream &out, const Complex &c);
friend std::istream &operator>>(std::istream &, Complex &);
public:
explicit Complex(double = 0.0, double = 0.0); // constructor
Complex operator+(const Complex &) const;
Complex operator-(const Complex &) const;
#endif
Complex.cpp:
#include "stdafx.h"
#include "Complex.h"
#include <iostream>
using namespace std;
istream &operator>>(istream &input, Complex &complex) // input
{
cout << "enter real part:\n";
input >> complex.real;
cout << "enter imag part: \n";
input >> complex.imaginary;
return input;
}
std::ostream &operator<<(std::ostream &out, Complex c) //output
{
out<<"real part: "<<c.real<<"\n";
out<<"imag part: "<<c.imag<<"\n";
return out;
}
You didn't friend the same function you defined. You friended the first, and defined the second:
friend std::ostream &operator<<(std::ostream &out, const Complex &c);
std::ostream &operator<<(std::ostream &out, Complex c)
Also, Is the member named imaginary or imag?
input >> complex.imaginary;
out<<"imag part: "<<c.imag<<"\n";