C++ Operator Overload conversion operator functions

Description

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;
  }
}



PreviousNext

Related