Search code examples
c++c++17operator-overloadingoperators

How to improve operator overloading for my class?


I have started learning C++. My teacher gave an assignment. I completed it (some polishing work is left) and everything seems to work but there is redundancy. My major issue is overloading. How to improve overloading in my class. Rather than writing all four functions (two for fstream and two for iostream), is it possible to write only two ? Any other suggestions to improve the code further ?

#include <iostream>
#include <fstream>
#include <string>
#include "../../my_func.hpp"
#define usi unsigned short int

using namespace std;

class book
{
    public:
    usi book_id = 0, price = 0, no_of_pages = 0, year_of_publishing = 0;
    string author_name = "NONE", publisher = "NONE";
    book(usi b_id = 0, usi b_price = 0, usi b_no_of_pages = 0, usi b_year_of_publishing = 0,
         const string& b_author_name = "NONE", const string& b_publisher = "NONE")
    {
        book_id = b_id;
        price = b_price;
        no_of_pages = b_no_of_pages;
        year_of_publishing = b_year_of_publishing;
        author_name = b_author_name;
        publisher = b_publisher;
    }
    friend fstream& operator >> (fstream& is, book& obj);
    friend fstream& operator << (fstream& os, const book& obj);
    friend istream& operator >> (istream &is, book& obj);
    friend ostream& operator << (ostream &os, const book& obj);
};

fstream& operator >> (fstream &is, book& obj)
{
    char ch;
    is >> obj.book_id >> obj.price 
       >> obj.no_of_pages >> obj.year_of_publishing;
    is.ignore(1, '\n'); //To take care of new line character
    getline(is, obj.author_name);
    getline(is, obj.publisher);
    return is;
}

fstream& operator << (fstream &os, const book& obj)
{
    os.operator<<(obj.book_id) << '\n' //calling operator function cuz it works 
               << obj.price << '\n'
               << obj.no_of_pages << '\n'
               << obj.year_of_publishing << '\n';
    os << obj.author_name << '\n'
       << obj.publisher << '\n';
    return os;
}

istream& operator >> (istream &is, book& obj)
{
    is >> obj.book_id >> obj.price 
       >> obj.no_of_pages >> obj.year_of_publishing;
    is.ignore(1, '\n'); //To take care of new line character
    getline(is, obj.author_name);
    getline(is, obj.publisher);
    return is;
}

ostream& operator << (ostream &os, const book& obj)
{
    os << obj.book_id << '\n'
       << obj.price << '\n'
       << obj.no_of_pages << '\n'
       << obj.year_of_publishing << '\n'
       << obj.author_name << '\n'
       << obj.publisher << '\n';
    return os;
}
int main()
{
    string path = ".\\C++_Experiment\\Exp-7\\Files\\Source.txt";
    book b1(12, 3000, 100, 2003, "Lol", "Pew"), b2, b3;
    fstream fio;
    fio.open(path, ios::out | ios::app | ios::in);
    if(fio) fio << b1;
    else cout <<  "error"; 
    fio.seekg(0, ios::beg);
    if(fio) fio >> b2 >> b3;
    cout << b2 << b3;
    fio.close();
    cout << "DONE";
    return 0;
}

Solution

  • You only need two overloads here. ifstream and ofstream inherit from istream and ostream respectively so if you have

    friend istream& operator >> (istream &is, book& obj);
    friend ostream& operator << (ostream &os, const book& obj);
    

    then those will work with cout and cin, and any fstream or stringstream objects as they also inherit from istream and ostream.