c++ - Implementing a non-member IO operator -
in assignment asked create product class, , have finished implementations except "non-member io operator". question found vague, asks me overload <<
, >>
operators work ostream , istream read product , print product console in order make main function work.
here see main function has cout or cin product's derived class sitem, wonder how should implement <<
>>
operators make 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: "; >> buf; sku(buf); cout << "name (no spaces): "; >> buf; name(buf); cout << "qty: "; >> ibuf; quantity(ibuf); cout << "qty needed: "; >> ibuf; qtyneeded(ibuf); cout << "is taxed? (1/0): "; >> ibuf; taxed(ibuf != 0); cout << "price: "; >> 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== " << (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 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 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 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 functions have been implemented except last two, io operators.
streamable class abstract class has no implementations.
you did wrong in many ways. best approach in case that.
first define interfaces stream operations, 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 use 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 product
can inherit interfaces:
class product : public istreamprintable , public istreamreadable { … };
you not have implement immediately. can implement methods in specific product classes sitem
, work out of box.
your method virtual std::fstream& store(std::fstream& file, bool addnewline = true)
total mess. passing fstream
object , opening specific file on it. wrong since unable write multiple objects single file. keep there ostream
object , not change state (do writing), cascade calls , avoid hard-coding file name.
Comments
Post a Comment