Reputation: 116
In my assignment I was asked to create the Product class, and I have finished all the implementations except the "non-member IO operator". The question I found it very vague, it asks me to overload the <<
and >>
operators to work with ostream and istream to read a Product from and print a Product to the console in order to make this main function work.
Here I see the main function has cout or cin to Product's derived class SItem, I wonder how I should implement the <<
>>
operators to make the main work.
My main:
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include "Product.h"
#include <fstream>
#ifdef TAB
# undef TAB
#endif
#define TAB '\t'
using namespace std;
namespace sict {
class SItem :public Product {
public:
SItem(const char* theSku, const char * theName) :Product(theSku, theName) {}
SItem() {}
virtual std::fstream& store(std::fstream& file, bool addNewLine = true)const {
if (!isEmpty()) {
file.open("ms4.txt", ios::out | ios::app);
file << sku() << TAB << name() << TAB << quantity() << TAB << qtyNeeded() << TAB
<< int(taxed()) << TAB << price() << endl;
file.clear();
file.close();
}
return file;
}
virtual std::fstream& load(std::fstream& file) {
file.open("ms4.txt", ios::in);
char buf[2000];
double dbuf;
int ibuf;
file >> buf;
sku(buf);
file >> buf;
name(buf);
file >> ibuf;
quantity(ibuf);
file >> ibuf;
qtyNeeded(ibuf);
file >> ibuf;
taxed(ibuf != 0);
file >> dbuf;
price(dbuf);
file.clear();
file.close();
return file;
}
virtual std::ostream& write(std::ostream& os, bool linear)const {
return isEmpty() ? os : (os << sku() << ": " << name() << ", qty: "
<< quantity() << ", qtyNeeded:" << qtyNeeded()
<< ", Cost: " << fixed << setprecision(2) << cost());
}
virtual std::istream& read(std::istream& is) {
char buf[2000];
double dbuf;
int ibuf;
cout << "Sku: ";
is >> buf;
sku(buf);
cout << "Name (no spaces): ";
is >> buf;
name(buf);
cout << "Qty: ";
is >> ibuf;
quantity(ibuf);
cout << "Qty Needed: ";
is >> ibuf;
qtyNeeded(ibuf);
cout << "Is taxed? (1/0): ";
is >> ibuf;
taxed(ibuf != 0);
cout << "Price: ";
is >> dbuf;
price(dbuf);
return is;
}
};
}
void dumpFile(fstream& f) {
f.open("ms4.txt", ios::in);
char ch;
while (!f.get(ch).fail()) {
cout.put(ch);
}
f.clear();
f.close();
}
using namespace sict;
void test() {
double res, val = 0.0;
fstream F("ms4.txt", ios::out);
F.close();
SItem S;
SItem T;
SItem U;
cout << "Enter Product info: " << endl;
cin >> S;
SItem V = S;
S.store(F);
T.load(F);
cout << "T: (store, load)" << endl;
cout << T << endl;
cout << "S: " << endl;
cout << S << endl;
cout << "V(S): " << endl;
cout << V << endl;
cout << "U=T & op= :" << endl;
U = T;
cout << U << endl;
cout << "Operator == :" << endl;
cout << "op== is " << (T == "1234" ? "OK" : "NOT OK") << endl;
cout << "op+=: " << endl;
U += 10;
cout << U << endl;
cout << "op+=double : " << endl;
res = val += U;
cout << res << "=" << val << endl;
}
int main() {
fstream F("ms4.txt", ios::out);
F.close();
SItem S;
SItem U("4321", "Rice");
cout << "Empty Prouduct:" << endl << S << endl;
cout << "U(\"4321\", \"Rice\"):" << endl << U << endl;
cout << "Please enter the following information:" << endl;
cout << "Sku: 1234" << endl;
cout << "Name(no spaces) : Blanket" << endl;
cout << "Qty : 12" << endl;
cout << "Qty Needed : 23" << endl;
cout << "Is taxed ? (1 / 0) : 1" << endl;
cout << "Price : 12.34" << endl;
test();
cout << "Please enter the following information:" << endl;
cout << "Sku: 1234" << endl;
cout << "Name(no spaces) : Jacket" << endl;
cout << "Qty : 12" << endl;
cout << "Qty Needed : 23" << endl;
cout << "Is taxed ? (1 / 0) : 0" << endl;
cout << "Price : 12.34" << endl;
test();
dumpFile(F);
cout << "----The End" << endl;
return 0;
}
This is my Product.h:
namespace sict {
class Product : public Streamable {
char sku_[MAX_SKU_LEN + 1];
char * name_;
double price_;
bool taxed_;
int quantity_;
int qtyNeeded_;
public:
Product();
Product(const char*, const char*, bool = true, double = 0, int = 0);
Product(const Product&);
virtual ~Product();
Product& operator=(const Product&);
//setters
void sku(const char*);
void price(double);
void name(const char*);
void taxed(bool);
void quantity(int);
void qtyNeeded(int);
//getters
const char* sku()const;
double price()const;
const char* name()const ;
bool taxed()const;
int quantity()const;
int qtyNeeded()const;
double cost()const;
bool isEmpty()const;
//member operators
bool operator==(const char*);
int operator+=(int);
int operator-=(int);
};
double operator+=(double, const Product&);
std::ostream& operator<<(std::ostream& ostr, const Product& p);
std::istream& operator >> (std::istream& istr, Product& p);
}
All the functions have been implemented except the last two, which are the IO operators.
Streamable class is an abstract class that has no implementations.
Upvotes: 0
Views: 88
Reputation: 37927
You did this wrong in many ways. Best approach in your case is do it like that.
First define interfaces for stream operations, for your products:
class IStreamPrintable
{
public:
virtual std::ostream& PrintToStream(std::ostream& outStream) const = 0;
};
class IStreamReadable
{
public:
virtual std::istream& ReadFromStream(std::istream& inputStream) = 0;
};
Secondly define stream operators which will use this interfaces.
std::ostream& operator<<(std::ostream& out, const IStreamPrintable& printObject)
{
return printObject.PrintToStream(out);
}
std::istream& operator>>(std::istream& input, IStreamReadable& readObject)
{
return printObject.ReadFromStream(input);
}
Now you Product
can inherit this interfaces:
class Product
: public IStreamPrintable
, public IStreamReadable
{
…
};
You do not have to implement it immediately. You can implement those methods in specific product classes SItem
and it will work out of the box.
Your method virtual std::fstream& store(std::fstream& file, bool addNewLine = true)
is total mess. You are passing fstream
object and opening some specific file on it. This is wrong since you are unable to write multiple objects to single file. Keep there ostream
object and do not change is state (do only writing), so you could cascade calls and so you could avoid hard-coding a file name.
Upvotes: 1