c++ overloading operator<< and operator>> - c++

class Book
{
string title;
int category;
public:
Book(const string& abook, int num);
string getTitle() const;
int getCategory() const;
friend ostream& operator<<(ostream& os, const Book& abook);
friend istream& operator>>(istream& is, Book& abook);
};
class Reader // base class
{
private:
string reader_name;
vector<Book> bookLists;
public:
string showname() const;
void add(const Book& abook); // organize book list
friend ostream& operator<<(ostream& os, const Reader& read_name);
friend istream& operator>>(istream& is, Reader& read_name);
};
class fantasyReader : public Reader { };
class horrorReader : public Reader { };
class scienceReader : public Reader { } ;
class mysteryReader : public Reader { };
I have two given text files.
1) Reader.txt <--- contains reader's name and category
For ex.
David <- reader's name
0 <- david is Fantasy reader
2) Book.txt <---- contains Book's title and category
For ex
Riddick <- Book's title
0 <- Book's category is fantasy
In the main function, array of pointers to Reader's obj are pointing each dervied class;
ex
Reader *obj[10];
int pos =0;
obj[pos++] = new fantasyReader();
The main goal is to organize book's list and put into a appropriate category and appropriate reader and write them into a new text file.
ex.
-David-
Riddick
-John-
The Crow
MY QUESTION
I'm not sure what should be inside of operator<< and operator>>
for class Book and class Reader

What should you put inside the overloaded << and >> operators?
Well, You can actually put anything inside the overloaded << and >> operator. They will just be simple function calls whenever a appropriate opportunity presents.
For eg:
Book obj;
cout<< obj; //Calls your overloaded << operator
As a general principle while overloading operators you should follow Principle of Least Astonishment, which means your code should be doing something similar what the operator does for a intrinsic data type. In the above example I would expect my << operator to display the contents of my Book class, in that case I would overload it as follows:
// Display title and category
ostream& operator<<(ostream& os, const Book& abook);
{
os << abook.title << "\n";
os << abook.category<< "\n";
return os; // must return ostream object
}
I need to return a stream object since it allows for the chaining ex:
Book obj1,obj2,obj3;
cout<<obj1<<obj2<<obj3;
Similarly, for >> Extraction operator I would expect the operator to get the data from user.
For ex:
Book obj;
cin>>obj; //Calls your overloaded >> operator
I would overload the >> operator as follows:
//Get the Book Title & Category from User
istream& operator>>(istream& is, Book& abook)
{
cout << "Enter Book Title: ";
is >> abook.title ;
cout << "Enter Book Category: ";
is >> abook.category;
return is; //Must return stream object
}
So, the bottomline is You can put any functionality inside >> and << operators but don't forget the Principle of Least Astonishment!

Related

How does cin read strings into an object of string class?

Reading some documentation online I found that istream class was part of C++ long before the string class was added. So the istream design recognizes basic C++ types such as double and int, but it is ignorant of the string type. Therefore, there are istream class methods for processing double and int and other basic types, but there are no istream class methods for processing string objects.
My question is if there are no istream class methods for processing string objects, why this program works and how ?
#include <iostream>
int main(void)
{
std::string str;
std::cin >> str;
std::cout << str << std::endl;
return 0;
}
This is possible with the use operator overloading. As shown in the below example, you can create your own class and overload operator>> and operator<<.
#include <iostream>
class Number
{
//overload operator<< so that we can use std::cout<<
friend std::ostream& operator<<(std::ostream &os, const Number& num);
//overload operator>> so that we can use std::cin>>
friend std::istream &operator>>(std::istream &is, Number &obj);
int m_value = 0;
public:
Number(int value = 0);
};
Number::Number(int value): m_value(value)
{
}
std::ostream& operator<<(std::ostream &os, const Number& num)
{
os << num.m_value;
return os;
}
std::istream &operator>>(std::istream &is, Number &obj)
{
is >> obj.m_value;
if (is) // check that the inputs succeeded
{
;//do something
}
else
{
obj = Number(); // input failed: give the object the default state
}
return is;
}
int main()
{
Number a{ 10 };
std::cout << a << std::endl; //this will print 10
std::cin >> a; //this will take input from user
std::cout << a << std::endl; //this will print whatever number (m_value) the user entered above
return 0;
}
By overloading operator>> and operator<<, this allows us to write std::cin >> a and std::cout << a in the above program.
Similar to the Number class shown above, the std::string class also makes use of operator overloading. In particular, std::string overloads operator>> and operator<<, allowing us to write std::cin >> str and std::cout << str, as you did in your example.
Because std::string overload the >> and << operator to return the type std::istream and std::ostream
How they overload it, you can look in this link that Mat gives.
You can create your own class and overload operators, too. Here is an example:
class MyClass
{
int numberOne;
double numberTwo;
public:
friend std::ostream& operator<<(std::ostream &out, const MyClass& myClass);
friend std::istream& operator>> (std::istream& in, MyClass& myClass);
};
// Since operator<< is a friend of the MyClass class, we can access MyClass's members directly.
std::ostream& operator<<(std::ostream &out, const MyClass& myClass)
{
out << myClass.numberOne << ' ' << myClass.numberTwo;
return os;
}
// Since operator>> is a friend of the MyClass class, we can access MyClass's members directly.
std::istream& operator>> (std::istream& in, MyClass& myClass)
{
in >> myClass.numberOne;
in >> myClass.numberTwo;
return in;
}
int main()
{
MyClass myClass;
std::cin >> myClass;
std::cout << myClass;
}
Because of operator overloading.
In your case, including <iostream> will include <string>, a specialization of std::basic_string. And std::basic_string has the non-member functions operator<< and operator>> defined.
Similarly, you can also overload operator<< and operator>> for your own custom types.

How to call a operator overloaded function from other functions / methods in c++?

I have another class object in my class. Ex:
ParkingMeter.h
class ParkingMeter
{
private:
ParkedCar pCar;
int minutesPurchased = 0;
public:
friend std::istream& operator >> (std::istream, ParkingMeter&);
};
ParkedCar.h
class ParkedCar
{
private:
std::string maker;
std::string model;
std::string color;
int licenseNumber = 0;
int minutesParked = 0;
public:
friend std::istream& operator >> (std::istream&, ParkedCar&);
friend std::ostream& operator << (std::ostream&, ParkedCar&);
};
So, when I enter the data for ParkingMeter object with it's respective operator overloaded, I want to call the overloaded function for the ParkedCar object aswell.
This is what I've got. The operator overloaded function for the ParkingMeter:
std::istream& operator>>(std::istream is, ParkingMeter& obj)
{
cout << "How many minutes to buy? ";
is >> obj.minutesPurchased;
cout << "Enter the information about your car:\n";
is >> obj.pCar;
return is;
}
But in my main file, the following code don't word:
ParkingMeter temp;
std::cin >> temp;
Thank you.
Solution
Thanks to #L. F. for pointing my silly mistake. :D
I've forgotten to use the & after std::istream in the arguments for the function:
friend std::istream& operator >> (std::istream, ParkingMeter&);
Now its works fine:
friend std::istream& operator >> (std::istream&, ParkingMeter&);

Overloading input operation >> in header or .cpp

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){}

Overloading operator for programming exercise

I'm in a programming class and need overloading explained to me. Simple question so hopefully I'll get an answer pretty quick. My understanding is that overloading an operator allows it to be used on a class. If that is true, then how would I overload >> to work with a class? I'm working on a small program to test out this idea and i'll post it here
#include <iostream>
#include <cstdlib>
#include "data.h"
using namespace std;
int main()
{
data obj;
cout << "What is the Number?" << endl;
cin >> obj;
system("pause");
return 0;
}
class data
{
public:
data operator >> (int);
private:
};
This page tells you mostly everything you need to know about operator overloading.
In short, nearly every operator in C++ can be overloaded for user-defined types. Some operators, like +, -, or >> must be defined outside of a class since they are free-standing, whereas others like copy assignment (=), must be defined within.
For your case, overloading the >> operator can be done in the following manner:
istream& operator>>(istream& in, data& d){
// Code here
return in;
}
Where it says "Code here", place the code you need to read into the data object.
For example, let us pretend that we were reading into a Point object with an x coordinate and a y coordinate. It is formatted in the stream like so: "(x,y)". The operator overload might look like this:
istream& operator>>(istream& in, Point& p){
char c;
in >> c;
if(c != '('){
in.clear(ios_base::failbit);
return in;
}
in >> p.x >> c >> p.y >> c;
return in;
}
This is just an example with minimal format checking, but hopefully it is enough to get you started.
Note that if members in your class are private, then you should friend the istream operator in the class definition:
class data{
...
public:
friend istream& operator>>(istream&, data&);
}
case1: no need to access private data
data.h.
class data {
public:
int i;
};
std::ostream& operator>> (std::istream&, data&); // better make operator >>
// a nonmember function
// if it doesn't need access
// to private data
data.cpp
#include "data.h"
std::istream& operator>> (std::istream& is, data& d) {
is>>d.i; // here we do some logic, we do what it means to do >> on
return is; // an instance of your data class and return reference to istream
}
case2: there is a need to access private data
data.h.
class data {
private:
int i;
friend std::ostream& operator>> (std::istream&, data&);
};
data.cpp
#include "data.h"
std::istream& operator>> (std::istream& is, data& d) {
is>>d.i; // here we do some logic, we do what it means to do >> on
return is; // an instance of your data class and return reference to istream
}
If you want to bolster your understanding of what operator overloading is, consider that essentially all operators on objects (such as "+", "++", "==", "!=", etc) are member functions.
Challenge yourself to recognize Obj a, b; a = b; as Obj a; Obj b; a.operator=(b);.
Overloading is purely providing a non-default implementation.
Here is a [terrible] overload of the cast-to-const-char* operator:
class BadWolf {
const char* m_text;
public:
BadWolf(const char* text) : m_text(text) {}
// if you really want the original text and ask for it with this function...
const char* tardisTranslation() const { return m_text; }
// but if you try to use me as a const char*...
operator const char* () const { return "bad wolf"; }
};
int main(int argc, const char* argv[]) {
BadWolf message("hello, sweetie");
std::cout << "Message reads: " << (const char*)message << std::endl;
std::cout << "Tardis translation: " << message.tardisTranslaction() << std::endl;
return 0;
}
I think this is what you want.
class data
{
friend istream& operator>>( istream&, data& );
private:
int data;
};
istream& operator>>( istream& in, data& d )
{
return in >> d.data;
}

Operator overloading >>

I am very new to C++ operator overloading and having some teething trouble.
I have defined:
void Graph::operator>>(const char* param)
The above function had to accept a string as input and then perform certain actions on the string. How do I call this function ? In what ways can I use it?
If you want to define operator so that you can do:
cin >> myGraph
cout << myGraph
You need to do something like this example below:
struct Entry
{
string symbol;
string original;
string currency;
Entry() {}
~Entry() {}
Entry(string& symbol, string& original, string& currency)
: symbol(symbol), original(original), currency(currency)
{}
Entry(const Entry& e)
: symbol(e.symbol), original(e.original), currency(e.currency)
{}
};
istream& operator>>(istream& is, Entry& en);
ostream& operator<<(ostream& os, const Entry& en);
Then implement operators:
istream& operator>>(istream& is, Entry& en)
{
is >> en.symbol;
is >> en.original;
is >> en.currency;
return is;
}
ostream& operator<<(ostream& os, const Entry& en)
{
os << en.symbol << " " << en.original << " " << en.currency;
return os;
}
Note: in this case the Entry is struct so it's members are public. If you don't want to make them public you can define the operator methods as friends so that they can access private members of Entry.
Here is how Entry would look like if it's members were not public:
struct Entry
{
private:
string symbol;
string original;
string currency;
public:
Entry() {}
~Entry() {}
Entry(string& symbol, string& original, string& currency)
: symbol(symbol), original(original), currency(currency)
{}
Entry(const Entry& e)
: symbol(e.symbol), original(e.original), currency(e.currency)
{}
friend istream& operator>>(istream& is, Entry& en);
friend ostream& operator<<(ostream& os, const Entry& en);
};
Graph myGraph;
myGraph >> "bla";
Note that yours is a weird use of operator>>(). Normally it's used like this:
NumericObject NumericObject::operator>>(NumericObject const& operand) const;
// bitshifts to the right
and
std::istream& operator>>(istream& in, StreamableObject& obj);
// parses a string representation of obj
I'm guessing what you are actually trying to do is be able to write code like this:
cin >> myGraph;
cout << myGraph;
Note that the graph object is not actually the object that gets its method called.
In this case, what you actually want to do is overload the global operator>> functions:
std::istream& operator>> (std::istream&, graph&);
std::ostream& operator<< (std::ostream&, const graph&);
If you're new to this, you picked a rather interesting (read as "not simple") problem to try to solve.
The operator overloads are not exactly functions. They are called indirectly when the compiler attempts to resolve code that looks something like this:
Graph g = new Graph();
g >> "do something";
I recommend you do NOT do this. Operator overloading can lead to VERY difficult bugs to troubleshoot, thanks to side effects. They are also hard on anyone who has to maintain your code (which might be you after you forgot why you did this).
Use operator overloads only when the meaning and use of them is intuitive.