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.
Related
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.
#include <iostream>
using namespace std;
class Complex
{
private:
int real, imag;
public:
Complex(int r = 0, int i =0)
{ real = r; imag = i; }
**friend ostream & operator << (ostream &out, const Complex &c);
friend istream & operator >> (istream &in, Complex &c);**
};
ostream & operator << (ostream &out, const Complex &c)
{
out << c.real;
out << "+i" << c.imag << endl;
return out;
}
istream & operator >> (istream &in, Complex &c)
{
cout << "Enter Real Part ";
in >> c.real;
cout << "Enter Imagenory Part ";
in >> c.imag;
return in;
}
int main()
{
Complex c1;
cin >> c1;
cout << "The complex object is ";
cout << c1;
return 0;
}
What is the use of passing the operator as a reference "& operator".
When we pass a normal operator we never pass the reference, but in the above code, we are passing the reference to the operator.
Can anyone explain the part where operator reference is passed?
In the code friend ostream & operator << the & is associated with the type overloaded operator returns.
So that it returns ostream & and istream & for the second one.
The overloaded operators:
Take the reference to istream or ostream object whcih is I/O object like cin/cout for console I/O or other type of stream object (I/O from/to string, etc).
Affect the state of the object so that data is read/written.
Return the reference to that object so that you can use these operators in sequence like:
Complex c1
Complex c2;
cin >> c1 >> c2;
Generally if a Declare one name (only) per declaration rule is adhered to,
then this allows to consistantly write a pointer/refrence "stuck" next to the type as:
istream& operator>> (istream& in, Complex& c)
{ //...
In this way it can be seen that the function named operator>> is returning a type istream& (a reference to an istream object).
This function takes 2 variables:
in of the type istream& (a reference to an istream object),
c of the type Complex& (a reference to a Complex object).
and similarly for:
ostream& operator<< (ostream& out, const Complex& c)
{ //...
The formatting of the code does not in anyway affect how the code is compiled.
So the functions definitions in this answer are exactly the same as in the question.
As to why use a reference, I suggest to read: When to use references vs. pointers
I created two classes and a constructor in each. Type followed a new class and constructors friends functions of the classes before.
#include <iostream>
using namespace std;
class clsAtmosfericConditions;
class clsDensity{
float density;
public:
clsDensity(){}
clsDensity(float densidad){
density = densidad;
}
friend istream& operator >>(istream &i, clsDensity &e);
friend ostream& operator <<(ostream &o, const clsDensity &s);
};
istream& operator >>(istream &i, clsDensity &e){
char sign;
i >> e.density >> sign >> sign >> sign >> sign >> sign >> sign;
return i;
}
ostream& operator <<(ostream &o, const clsDensity &s){
o << s.density << " Kg/m^3";
return o;
}
class clsDynamicViscocity{
double dynamicViscocity;
public:
clsDynamicViscocity(){}
clsDynamicViscocity(double viscocidadDinamica){
dynamicViscocity = viscocidadDinamica;
}
friend istream& operator >>(istream &i, clsDynamicViscocity &e);
friend ostream& operator <<(ostream &o, const clsDynamicViscocity &s);
};
istream& operator >>(istream &i, clsDynamicViscocity &e){
char sign;
i >> e.dynamicViscocity >> sign >> sign >> sign >> sign >> sign;
return i;
}
ostream& operator <<(ostream &o, const clsDynamicViscocity &s){
o << s.dynamicViscocity << " N/m^2";
return o;
}
class clsAtmosfericConditions{
friend clsDynamicViscocity::clsDynamicViscocity(double viscocidadDinamica);
friend clsDensity::clsDensity(float densidad);
public:
float kinematicViscocity();
};
float kinematicViscocity(){
float kinematicViscocity;
kinematicViscocity = dynamicViscocity/density; //Here is where IDE gives me the error
return kinematicViscocity;
}
The IDE displays an error in the function: error: 'dynamicViscocity' undeclares (first use this function)
I checked on some websites and I see no need to pass values by reference builder when you do the operation.
Couple of problems here.
dynamicViscocity is a member of class clsDynamicViscocity. kinematicViscocity is not a member of any class, but I suspect is is intended to be a member of clsAtmosfericConditions. Regardless, kinematicViscocity is not a member of clsDynamicViscocity, so in order to operate on dynamicViscocity, it needs an object of type clsDynamicViscocity to provide dynamicViscocity.
Second, the visibility (public, private, protected) of dynamicViscocity is not specified, so C++ defaults to the most restrictive, private. A private member cannot be seen except by the object and those the object has defined as friends.
So kinematicViscocity has no dynamicViscocity and even if it did, it cannot see dynamicViscocity.
Suggested solution
Change the definition of kinematicViscocity to
float clsAtmosfericConditions::kinematicViscocity(const clsDynamicViscocity & vis,
const clsDensity & den)
{
float kinematicViscocity;
kinematicViscocity = vis.getDynamicViscocity() / den.getDensity();
return kinematicViscocity;
}
to provide a clsDynamicViscocity to kinematicViscocity and add a getter function
double getDynamicViscocity() const
{
return dynamicViscocity;
}
to clsDynamicViscocity.
The same needs to be done to access density from clsDensity.
EDIT
Waaaait a second...
Finally figured out what you are trying to do here:
friend clsDynamicViscocity::clsDynamicViscocity(double viscocidadDinamica);
friend clsDensity::clsDensity(float densidad);
A class declares who they will allow to see and use their hidden internals. A class cannot declare who's hidden internals they can see. Think of it this way, Bob can be friends with Alice and show her his secrets, but Bob cannot force Alice to be his friend and show him her secrets. Alice has to make that decision herself.
What the above means is the two methods can can violate encapsulation and see the hidden internals of clsAtmosfericConditions. clsAtmosfericConditions cannot however see the internals of clsDynamicViscocity or clsDensity.
clsDynamicViscocity and clsDensity have to friend class clsAtmosfericConditions to allow clsAtmosfericConditions to see into them, not the other way around.
So
clsDensity()
{
friend class clsAtmosfericConditions;
...
}
and
clsDynamicViscocity()
{
friend class clsAtmosfericConditions;
...
}
Now change kinematicViscocity to look like this:
float clsAtmosfericConditions::kinematicViscocity(const clsDynamicViscocity & vis,
const clsDensity & den)
{
float kinematicViscocity;
kinematicViscocity = vis.dynamicViscocity / den.density;
return kinematicViscocity;
}
and you are golden.
The original solution with the getters is a better solution as it requires no friends whatsoever and is much less tightly coupled. The guts of clsDynamicViscocity and clsDensity can be radically changed without breaking clsAtmosfericConditions so long as the getter function prototypes remain the same and clsAtmosfericConditions is granted no more access to clsDynamicViscocity and clsDensity than is required to get data.
If i want to overload the operator ">>" and this is the line inside my .h file
friend istream &operator >> (istream& input,const Money&m2);
Do I want for instance
friend istream &operator >> (istream& input,const Money&m2){
input >> m2.dollar;
return input;
}
into my header file or into my class file. If i were to put it into my class file how would the function be called? Would something like this be okay?
const Money Money::&operator >> (istream& input,const Money&m2)
The class name is "Money.cpp"
The input streaming operator takes a reference to a non-const std::istream, and a reference to a non-const object into which the data is to be read. You can define it as a friend of the class for efficiency (direct access to the member variables), but if you already provide efficient mechanisms for setting those values, you may want to consider whether it needs to be a friend at all.
In the example below, I define a class Money, which represents some value (as a double-precision floating-point value, which is pretty bad, but just an example) and the ISO currency code (as a std::string). I then define an input streaming operator that reads input in the format "13.99 GBP" and an output streaming operator that writes the values in the same format.
Live example: http://coliru.stacked-crooked.com/a/d3e24b4fd697f773
money.hpp
class Money {
public:
Money(double value, const std::string& code);
const std::string& currencyCode() const;
double value() const;
friend std::istream& operator>>(std::istream&, Money&);
private:
double value_;
std::string code_;
};
std::istream& operator>>(std::istream& in, Money& m);
std::ostream& operator<<(std::ostream& out, const Money& m);
money.cpp
Money::Money(double value, const std::string& code)
: value_(value), code_(code) {}
const std::string& Money::currencyCode() const {
return code_;
}
double Money::value() const {
return value_;
}
std::istream& operator>>(std::istream& in, Money &m) {
in >> m.value_ >> m.code_;
return in;
}
std::ostream& operator<<(std::ostream& out, const Money& m) {
out << m.value() << " " << m.currencyCode();
return out;
}
Some points to bear in mind:
In general, the output streaming operator need not be a friend; there is usually a way to access the information it needs through the public member functions of the class, without losing efficiency.
The input streaming operator is a friend only for efficiency reasons; we can stream directly into the member variables.
For the input streaming operator, the second parameter (the object you're reading into) must not be const - an input operation changes the object being read into.
For the output streaming operator, the second parameter (the object you're writing out) should be const - an output operation should not change the object being written out.
If the constructor performs some non-trivial validation (e.g. checking that the std::string contains a valid ISO currency code), we should not bypass that validation by reading directly into the member variable in our input streaming operator. Instead, we should read into a local double and a local string, then construct a Money object, handing validation off to the already-written constructor (see the example below; the header is identical, except for removing the friend declaration from the class).
Live example: http://coliru.stacked-crooked.com/a/233ac7c17e51f612
money.cpp (validation in constructor)
Money::Money(double value, const std::string& code)
: value_(value), code_(code) {
if (code_ != "GBP") throw std::runtime_error("Must be GBP");
}
const std::string& Money::currencyCode() const {
return code_;
}
double Money::value() const {
return value_;
}
std::istream& operator>>(std::istream& in, Money &m) {
double value(0.0);
std::string code;
in >> value >> code;
m = Money(value, code);
return in;
}
std::ostream& operator<<(std::ostream& out, const Money& m) {
out << m.value() << " " << m.currencyCode();
return out;
}
If you put it in your header any change in the function definition requires recompilation of any files that include it. If you define it in the .cpp file then you don't and the linker will sort out calling it.
I don't know what is bothering you so have this example and see if it clears your doubt.
Run Here: http://ideone.com/K90L13
.h
#include <iostream>
#include <istream>
using namespace std;
class A{
int p;
public:
friend istream & operator >> (istream&,A&);
friend ostream & operator << (ostream&,A&);
};
.cpp
istream & operator >> (istream &input, A &obj){
input >> obj.p;
return input;
}
ostream & operator << (ostream &output, A &obj){
output << obj.p;
return output;
}
int main(){
A a;
cin >> a;
cout << a;
}
answered.
Function name in class field should be
std::istream &operator >> (istream& input,const Money&m2){}
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";