C++ Class Definition Creating length objects
#include <iostream> #include <iomanip> #include <memory> #include <string> #include <typeinfo> #include <vector> using std::string; class MyLength/*from ww w .j ava2 s. com*/ { protected: long mm {}; static double mmPerInch; static double mmPerMeter; static double inchesPerYard; static double yardsPerPerch; public: MyLength() = default; // Default constructor MyLength(long n) : mm(n){} // Constructor from millimeters virtual double length() const { return mm; };// Return the length }; class Inches: public MyLength { protected: double inches {}; public: Inches() = default; Inches(double ins) :MyLength {static_cast<long>(0.5 + mmPerInch*ins)}, inches {ins} {} double length() const override { return inches; } // Return the length }; class Meters: public MyLength { protected: double meters {}; public: Meters() = default; Meters(double m) :MyLength {static_cast<long>(0.5 + mmPerMeter*m)}, meters {m} {} double length() const override { return meters; } // Return the length }; class Yards: public MyLength { protected: double yards {}; public: Yards() = default; Yards(double yds) :MyLength {static_cast<long>(0.5 + inchesPerYard*mmPerInch*yds)}, yards {yds} {} double length() const override { return yards; } // Return the length }; class Perches: public MyLength { protected: double perches {}; public: Perches():MyLength(){} Perches(double pch) :MyLength {static_cast<long>(0.5 + yardsPerPerch*inchesPerYard*mmPerInch*pch)}, perches {pch} {} double length() const override { return perches; } // Return the length }; // Initialize static data members double MyLength::mmPerInch {25.4}; double MyLength::mmPerMeter {1000.0}; double MyLength::inchesPerYard {36.0}; double MyLength::yardsPerPerch {5.5}; // Read a length from the keyboard std::shared_ptr<MyLength> readLength() { double value {}; // Stores the length value string units; // Stores the units for(;;) { std::cout << "\nEnter a length: "; std::cin >> std::skipws >> value; // Skip whitespace and read the value if (!value) return nullptr; getline(std::cin, units); // Rest of line is units int index {units.find_first_not_of(" ")}; // Find first non-blank in units // Return the object type corresponding to the units switch(toupper(units[index])) { case 'M': return std::make_shared<Meters>(value); case 'I': return std::make_shared<Inches>(value); case 'Y': return std::make_shared<Yards>(value);; case 'P': return std::make_shared<Perches>(value); default: std::cout << "\nInvalid units. Re-enter length: "; break; } } } int main() { std::vector<std::shared_ptr<MyLength> > pLengths; std::cout << "\nYou can enter lengths in inches, meters, yards, or perches." << "\nThe first character following the number specifies the units." << "\nThis can be i, m, y, or p, for inches, meters, yards, or perches." << "\ne.g. '22 ins' is 22 inches, '3.5 p' or '3.5perches' is 3.5 perches, '1y' is 1 yard." << std::endl << "\nPlease enter a length followed by the units or 0 to end:"; while (true) { auto p = readLength(); if (!p)break; pLengths.push_back(p); } // Output the lengths - we must figure out what type they are to display the units for(auto p : pLengths) { string units(" invalid type"); if(typeid(*p)==typeid(Inches)) units = " inches"; else if(typeid(*p)==typeid(Meters)) units = " meters"; else if(typeid(*p)==typeid(Yards)) units = " yards"; else if(typeid(*p)==typeid(Perches)) units = " perches"; std::cout << "\nLength is " << std::fixed << std::setprecision(2) << p->length() << units << " which is " << static_cast<long>(p->MyLength::length()) << " millimeters." << std::endl; } }