Convertion problem

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Chiller

    Convertion problem


    I'm in the process of writing a class that performs functions on a Distance
    object. The object is created by entering details as "Distance a (5, km)" or
    "Distance b (3, cm)" etc.

    I wish to write a function that I can call to "as required by comparison
    functions" to convert any value to a mm value so that when I'm comparing
    Distance objects the values will all be the same.

    The code I've come up with is below; however, it doesn't work correctly.
    When I try and compile it the compiler advises it must return a value;
    however, I simply want to replace the object that called to it with the new
    values, ie Distance a (2, cm) to Distance a (20, mm) etc.

    The constructor used in the class is as follows:

    Distance :: Distance (int n, char m) : nu(n), me(m) {}



    My function as follows:

    int Distance::to_mm ()
    {

    if ( me == km)

    {

    nu = nu/1000000;

    me = mm;

    }

    if (me == m)

    {

    nu = nu/1000;

    me = mm;

    }

    if ( me == cm)

    {

    nu = nu/10;

    me = m;

    }

    }

    Thanks for any help



  • Victor Bazarov

    #2
    Re: Convertion problem

    "Chiller" <...@...> wrote...[color=blue]
    >
    > I'm in the process of writing a class that performs functions on a[/color]
    Distance[color=blue]
    > object. The object is created by entering details as "Distance a (5, km)"[/color]
    or[color=blue]
    > "Distance b (3, cm)" etc.
    >
    > I wish to write a function that I can call to "as required by comparison
    > functions" to convert any value to a mm value so that when I'm comparing
    > Distance objects the values will all be the same.
    >
    > The code I've come up with is below; however, it doesn't work correctly.
    > When I try and compile it the compiler advises it must return a value;
    > however, I simply want to replace the object that called to it with the[/color]
    new[color=blue]
    > values, ie Distance a (2, cm) to Distance a (20, mm) etc.
    >
    > The constructor used in the class is as follows:
    >
    > Distance :: Distance (int n, char m) : nu(n), me(m) {}
    >
    >
    >
    > My function as follows:
    >
    > int Distance::to_mm ()[/color]

    You declared your function as returning an int. That means that inside
    the body of your function _all_ control paths have to lead to a statement
    of the kind

    return <some_expressio n_convertible_t o_int>;

    If you didn't intend to return anything from your function 'to_mm', you
    ought to declare it 'void':

    void Distance::to_mm ()
    [color=blue]
    > {
    >
    > if ( me == km)
    >
    > {
    >
    > nu = nu/1000000;
    >
    > me = mm;
    >
    > }
    >
    > if (me == m)[/color]

    I'd recommend

    else if (me == m)
    [color=blue]
    >
    > {
    >
    > nu = nu/1000;
    >
    > me = mm;
    >
    > }
    >
    > if ( me == cm)[/color]

    The same here.
    [color=blue]
    >
    > {
    >
    > nu = nu/10;
    >
    > me = m;
    >
    > }
    >
    > }
    >
    > Thanks for any help[/color]

    HTH

    Victor


    Comment

    • Chiller

      #3
      Re: Convertion problem


      I've implemented the function to change all values to "mm" when calling to a
      comparison function; however, it just isn't working. In my TEST_DRIVER at
      the bottom of the .cpp file I've inluded a greater than test for two values;
      however it believes that 5 m is greater than 4 km, so I've obviously done
      something wrong.

      I've included my revised .cpp file and .h file below. I'd appreciate some
      advice on what I'm doing wrong.

      Thanks for any help


      ..cpp file
      *************** ********
      #include "Distance.h "

      #include <iostream>

      using namespace std;

      /*-------------------------------------------------------*\

      | implementation of member functions |

      \*-------------------------------------------------------*/

      // constructors

      Distance :: Distance (int n, char m) : nu(n), me(m) {}

      Distance :: Distance (void) : nu(0), me(2) {}

      enum {mm, cm, m, km};

      // access functions

      int Distance :: number (void)

      {

      return nu;

      }

      char Distance :: measure (void)

      {

      return me;

      }

      //Convertion function to ensure all values are in the same unit of measure

      void Distance::to_mm ()

      {

      if ( me == km)

      {

      nu = nu/1000000;

      me = mm;

      }

      else if (me == m)

      {

      nu = nu/1000;

      me = mm;

      }

      else if (me == cm)

      {

      nu = nu/10;

      me = cm;

      }

      }





      // Overload of the "=" operator

      Distance & Distance::opera tor= (Distance const & right_operand)

      {

      nu = right_operand.n u;

      me = right_operand.m e;

      return *this;

      }

      // Overload of the "==" operator

      bool Distance::opera tor == ( Distance const & rhs )

      {

      to_mm();

      return ( nu == rhs.nu && me == rhs.me );

      }

      //Overload of the != operator

      bool Distance::opera tor != ( Distance const & rhs )

      {

      to_mm();

      return ( nu != rhs.nu && me != rhs.me );

      }

      //Overload of the < operator

      bool Distance::opera tor < (Distance const & rhs)

      {

      to_mm();

      return ( nu < rhs.nu && me < rhs.me );

      }

      //Overload of the <= operator

      bool Distance::opera tor <= (Distance const & rhs)

      {

      to_mm();

      return (nu <= rhs.nu && me <= rhs.me);

      }

      //Overload of the > operator

      bool Distance::opera tor > (Distance const & rhs)

      {

      to_mm();

      return (nu > rhs.nu && me > rhs.me);

      }

      //Overload of the >= operator

      bool Distance::opera tor >= (Distance const & rhs)

      {

      to_mm();

      return (nu >= rhs.nu && me >= rhs.me);

      }

      // provide an overload of "<<" for easy display

      ostream& operator<< (ostream& out, Distance& d)

      {

      out << "(" << d.number() << ", ";

      switch (d.measure())

      {

      case mm:

      out << "mm";

      case cm:

      out << "cm";

      break;

      case m:

      out << "m";

      break;

      case km:

      out << "km";

      break;

      }

      out << ")";

      return out;

      }

      /*-------------------------------------------------------*\

      | test driver for the Distance class |

      \*-------------------------------------------------------*/

      #ifdef TEST_DISTANCE // .... Distance class .... test driver

      int main (void)

      {

      // create test input

      Distance a = Distance (6, cm);

      Distance b (4, km);

      Distance c (2, m);

      Distance d;

      Distance e (5, m);

      Distance z1 = a = b;

      cout << a << endl << b << endl << c << endl << d << endl << e << endl <<

      endl;

      cout << a <<endl << endl;

      cout << "The results of comparing various Distance values :" << endl;

      cout << "Distance a == Distance e : ";

      cout << (a == e ? "true" : "false") << endl;

      cout << "Distance a != Distance e : ";

      cout << (a != e ? "true" : "false") << endl;

      cout << "Distance a < Distance c : ";

      cout << (a < c ? "true" : "false") << endl;

      cout << "Distance a <= Distance c : ";

      cout << (a <= c ? "true" : "false") << endl;

      cout << "Distance a > Distance c : ";

      cout << (a > c ? "true" : "false") << endl;

      cout << "Distance a >= Distance b : ";

      cout << (a >= c ? "true" : "false") << endl;

      cout << "Distance a > Distance e : ";

      cout << (a > e ? "true" : "false") << endl;

      cin.ignore();

      return 0; // normal termination

      }

      #endif


      ..h file
      *************** **********


      #ifndef DISTANCE_H

      #define DISTANCE_H

      #include <iostream>

      using namespace std;

      class Distance

      {

      public :

      Distance (int, char) ; // constructor - takes int and char values

      Distance (void) ; // default - zero

      //access member functions

      int number (void);

      char measure (void);

      //overloads

      Distance & Distance::opera tor= (Distance const & right_operand);

      bool operator == ( Distance const &rhs );

      bool operator != ( Distance const &rhs );

      bool operator < ( Distance const &rhs );

      bool operator <= ( Distance const &rhs );

      bool operator > ( Distance const &rhs );

      bool operator >= ( Distance const &rhs );

      void Distance::to_mm ();

      private :

      int nu ; // the value

      char me ; // the unit of measure (m)

      } ;

      // provide an overload of "<<" for easy display

      ostream& operator<< (ostream&, const Distance&);

      #endif




      Comment

      • Siemel Naran

        #4
        Re: Convertion problem

        "Chiller" <...@...> wrote in message
        news:d126b8f17c ec2a78970062f1e 8b79e43@news.te ranews.com...
        [color=blue]
        > using namespace std;[/color]

        Not in header files.

        [color=blue]
        > Distance :: Distance (int n, char m) : nu(n), me(m) {}
        >
        > Distance :: Distance (void) : nu(0), me(2) {}
        >
        > enum {mm, cm, m, km};[/color]

        enum Measure {mm=1, cm=10, m=1000, km=1000000};

        Furthermore, if you do operator>, operator-, etc most often, it's best to
        store the result in millimeters.

        Distance :: Distance (int n=0, Measure m=mm) : d_n(n*m) {}

        Ultimately it's your call. BTW, member function measure should probably
        return a Measure, not a char. And the constructor should take a Measure.

        [color=blue]
        > void Distance::to_mm ()
        >
        > {
        >
        > if ( me == km)
        >
        > {
        >
        > nu = nu/1000000;
        >
        > me = mm;
        >
        > }[/color]

        Seems you want multiplication?

        [color=blue]
        > // Overload of the "=" operator
        >
        > Distance & Distance::opera tor= (Distance const & right_operand)
        >
        > {
        >
        > nu = right_operand.n u;
        >
        > me = right_operand.m e;
        >
        > return *this;
        >
        > }[/color]

        Compiler generated constructor is fine; no need to write your own.

        [color=blue]
        > // Overload of the "==" operator
        >
        > bool Distance::opera tor == ( Distance const & rhs )
        >
        > {
        >
        > to_mm();
        >
        > return ( nu == rhs.nu && me == rhs.me );
        >
        > }[/color]

        Really? I think 1000mm equals 1m, so

        Distance(1000,D istance::mm) == Distance(1,m)

        ought to return true. So the comparison function ought to take the measure
        into account. If you store all values in mm inside the class, then
        operator== is very easy to write.

        [color=blue]
        > //Overload of the != operator
        >
        > bool Distance::opera tor != ( Distance const & rhs )
        >
        > {
        >
        > to_mm();
        >
        > return ( nu != rhs.nu && me != rhs.me );
        >
        > }[/color]

        Should probably be implemented in terms of operator==.

        return !(lhs==rhs);

        Also, probably make operator== and the others as non-members for symmetry if
        there is a one-arg non-explicit constructor.

        [color=blue]
        > // provide an overload of "<<" for easy display
        >
        > ostream& operator<< (ostream& out, Distance& d)
        >
        > {
        >
        > out << "(" << d.number() << ", ";
        >
        > switch (d.measure())
        >
        > {
        >
        > case mm:
        >
        > out << "mm";
        >
        > case cm:
        >
        > out << "cm";
        >
        > break;
        >
        > case m:
        >
        > out << "m";
        >
        > break;
        >
        > case km:
        >
        > out << "km";
        >
        > break;
        >
        > }
        >
        > out << ")";
        >
        > return out;
        >
        > }[/color]

        If you used

        enum {mm, cm, m, km};

        then just

        out << "(" << d.number() << ", " << g_table[d.measure()] << ')';

        where

        const char g_table[4] = { "mm", "cm", "m", "km" };

        What about operator>>, which is harder?


        Comment

        • Siemel Naran

          #5
          Re: Convertion problem

          "Chiller" <...@...> wrote in message
          news:cfb731d5da 482281453f42207 0cf3a36@news.te ranews.com...
          [color=blue]
          > Distance :: Distance (int n, char m) : nu(n), me(m) {}
          >
          >
          >
          > My function as follows:
          >
          > int Distance::to_mm ()
          > {
          >
          > if ( me == km)
          >
          > {
          >
          > nu = nu/1000000;
          >
          > me = mm;
          >
          > }
          >
          > if (me == m)
          >
          > {
          >
          > nu = nu/1000;
          >
          > me = mm;
          >
          > }
          >
          > if ( me == cm)
          >
          > {
          >
          > nu = nu/10;
          >
          > me = m;
          >
          > }
          >
          > }[/color]

          Should all the multiplication signs be division? Also, the last else says
          me=m, but the others are me=mm.


          Comment

          • Buster

            #6
            Re: Conversion problem

            Distances are continuous. Storing them as integers is silly.
            And as Siemel Naran seems to have wanted to say, all those
            divisions should be multiplications .

            --
            Regards,
            Buster.

            Comment

            • Siemel Naran

              #7
              Re: Conversion problem

              "Buster" <noone@nowhere. com> wrote in message
              news:c5dg49$prf $2@newsg1.svr.p ol.co.uk...
              [color=blue]
              > Distances are continuous. Storing them as integers is silly.
              > And as Siemel Naran seems to have wanted to say, all those
              > divisions should be multiplications .[/color]

              Storing them as integers might make sense for some applications.


              Comment

              Working...