C++ Operator Overload conversion operator functions
#include <iostream> #include <iomanip> #include <memory> #include <string> #include <typeinfo> #include <vector> using std::string; class Inches;//from w ww . j a va 2s . co m class Yards; class Meters; class Perches; class MyLength { 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 virtual operator Inches()const;// Conversion to Inches virtual operator Yards()const; // Conversion to Yards virtual operator Meters()const;// Conversion to Meters virtual operator Perches()const;// Conversion to Perches }; 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 // Inherited conversion to meters is OK operator Inches() const override { return *this; } operator Yards()const override;// Conversion to Yards operator Perches()const override;// Conversion to Perches }; 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 // Inherited conversion to meters is OK operator Yards() const override { return *this; } operator Perches()const override; // Conversion to Perches operator Inches()const override; // Conversion to Inches }; 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 operator Perches() const override { return *this; } operator Inches()const override; // Conversion to Perches operator Yards()const override; // Conversion to Yards }; // Initialize static data members double MyLength::mmPerInch {25.4}; double MyLength::mmPerMeter {1000.0}; double MyLength::inchesPerYard {36.0}; double MyLength::yardsPerPerch {5.5}; MyLength::operator Inches()const { return Inches {mm / mmPerInch}; } // Conversion to Inches MyLength::operator Yards()const { return Yards {mm / (mmPerInch*inchesPerYard)}; } // Conversion to Yards MyLength::operator Meters()const { return Meters {mm / mmPerMeter}; } // Conversion to Meters MyLength::operator Perches()const { return Perches {mm / (mmPerInch*inchesPerYard*yardsPerPerch)}; } // Conversion to Perches Inches::operator Yards()const { return Yards {inches / inchesPerYard}; } // Conversion to Yards Inches::operator Perches()const { return Perches {inches / (inchesPerYard*yardsPerPerch)}; } // Conversion to Perches Yards::operator Perches()const { return Perches {yards / yardsPerPerch}; } // Conversion to Perches Yards::operator Inches()const { return Inches {yards * inchesPerYard}; } // Conversion to Inches Perches::operator Inches()const { return Inches {perches * yardsPerPerch*inchesPerYard}; } // Conversion to Perches Perches::operator Yards()const { return Yards {perches * yardsPerPerch}; } // Conversion to Yards // 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); } for(auto p : pLengths){ std::cout << "\nLength is " << static_cast<Inches>(*p).length() << std::fixed << std::setprecision(2) << " inches, " << static_cast<Yards>(*p).length() << " yards, " << static_cast<Meters>(*p).length() << " meters, " << static_cast<Perches>(*p).length() << " perches, " << static_cast<long>(p->MyLength::length()) << " millimeters." << std::endl; } }