Converting length objects, Length classes with conversion operator functions - C++ Class

C++ examples for Class:Operator Overload

Description

Converting length objects, Length classes with conversion operator functions

Demo Code

                                                     
#include <iostream>
#include <iomanip>
#include <memory>
#include <string>
#include <typeinfo>
#include <vector>
using std::string;
                                                        
class Inches;/*from w ww.  j  a  v  a  2  s. c om*/
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
    unsigned 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;
  }
}

Result


Related Tutorials