C++ fstream Writing & reading base and derived class objects
#include <fstream> #include <iostream> #include <string> #include <vector> #include <iomanip> class Pool/*from w ww .java2 s . com*/ { protected: double length {1.0}; double width {1.0}; double height {1.0}; public: // Constructors Pool(double lv, double wv, double hv) : length {lv}, width {wv}, height {hv} {} Pool() = default; // Default constructor Pool(const Pool& pool) // Copy constructor : length {pool.length}, width {pool.width}, height {pool.height} {} virtual double volume() const // Calculate the volume { return length*width*height; } // Member stream I/O functions virtual std::ostream& put(std::ostream& out) const // Stream output { return out << std::setw(10) << length << ' ' << std::setw(10) << width << ' ' << std::setw(10) << height << '\n'; } virtual std::istream& get(std::istream& in) // Stream input { return in >> length >> width >> height; } }; inline std::ostream& operator<<(std::ostream& out, const Pool& pool) { return pool.put(out); } inline std::istream& operator>>(std::istream& in, Pool& pool) { return pool.get(in); } using std::string; class Carton : public Pool { private: string material; public: // Constructor explicitly calling the base constructor Carton(double lv, double wv, double hv, string str = "cardboard") : Pool {lv, wv, hv} { material = str; } Carton() = default; // Function to calculate the volume of a Carton object double volume() const override { double vol {(length - 0.5)*(width - 0.5)*(height - 0.5)}; return vol > 0.0 ? vol : 0.0; } // Stream output std::ostream& put(std::ostream& out) const override { out << std::left << std::setw(15) << material << ' '; // Write the material return Pool::put(out); // Write the sub-object } // Stream input std::istream& Carton::get(std::istream& in) override { in >> material; // Read the string return Pool::get(in); // Read the sub-object } }; using std::string; int main() try { std::vector<Pool> pools {Pool {1.0, 2.0, 3.0}, Pool {2.0, 2.0, 3.0}, Pool {3.0, 2.0, 2.0}, Pool {4.0, 2.0, 3.0}}; std::vector<Carton> cartons {Carton {6.0, 7.0, 8.0, "plastic"}, Carton {5.0, 7.0, 9.0, "wood"}, Carton {5.0, 6.0, 5.0}}; const string filename {"D:\\Example_Data\\containers.txt"}; std::ofstream out {filename}; if (!out) throw std::ios::failure {string {"Failed to open output file "} +filename}; for (auto& pool : pools) out << pool; // Write a Pool object out.close(); // Close the output stream std::cout << pools.size() << " Pool objects written to " << filename << std::endl; std::ifstream in {filename}; // Create a file input stream if (!in) // Make sure it's valid throw std::ios::failure {string("Failed to open input file ") + filename}; std::cout << "Reading Pool objects from the file:\n"; Pool pool; while (true) { in >> pool; // Read an object from the file if (!in) break; // End if EOF std::cout << pool; // Output the object read } in.close(); // Close the input stream out.open(filename); // Open the output file for (auto& carton : cartons) out << carton; // Write a Carton object out.close(); // Close the output stream std::cout << cartons.size() << " Carton objects written to " << filename << std::endl; in.open(filename); std::cout << "Reading Carton objects from the file:\n"; Carton carton; while (true) { in >> carton; // Read a Carton object from the file if (!in) break;// End if EOF std::cout << carton;// Output the object read } in.close(); // Close the input stream } catch (std::exception& ex) { std::cout << typeid(ex).name() << ": " << ex.what() << std::endl; }