Standardised unit of measure - please help

C

Chiller

I'm now getting close to finishing my Distance class. In the code below I
have included a number of overload operators that test for equality etc.
I've also added more code in the TEST_DISTANCE driver to test the code.

I now have 2 remaining problems:

1. The code will allow for the input of distances in either cm, m or km
values; however, it isn't smart enough to convert values of different types
(ie cm and km) for correct follow on processing. I would like to add
something to my class that will take any of the three inputs and convert
them to metres for all subsequent operations.

Could someone please give me some examples on how I can achive this.

2. I would also like to include a unary operator- operation which will
return the negative of a Distance value. All my attempts thus far have only
subtracted values. Could someone please advise me on how I must implement
this.

Thanks

..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) const;

char measure (void) const;

//overloads

Distance & Distance::eek:perator= (Distance const & right_operand);

bool operator == ( Distance const &rhs ) const;

bool operator != ( Distance const &rhs ) const;

bool operator < ( Distance const &rhs ) const;

bool operator <= ( Distance const &rhs ) const;

bool operator > ( Distance const &rhs ) const;

bool operator >= ( Distance const &rhs ) const;

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


..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(1) {}

enum {cm, m, km};

// access functions

int Distance :: number (void) const

{

return nu;

}

char Distance :: measure (void) const

{

return me;

}

// Overload of the "=" operator

Distance & Distance::eek:perator= (Distance const & right_operand)

{

nu = right_operand.nu;

me = right_operand.me;

return *this;

}

// Overload of the "==" operator

bool Distance::eek:perator == ( Distance const & rhs ) const

{

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

}

//Overload of the != operator

bool Distance::eek:perator != ( Distance const & rhs ) const

{

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

}

//Overload of the < operator

bool Distance::eek:perator < (Distance const & rhs) const

{

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

}

//Overload of the <= operator

bool Distance::eek:perator <= (Distance const & rhs) const

{

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

}

//Overload of the > operator

bool Distance::eek:perator > (Distance const & rhs) const

{

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

}

//Overload of the >= operator

bool Distance::eek:perator >= (Distance const & rhs) const

{

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

}

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

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

{

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

switch (d.measure())

{

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;

cin.ignore();

return 0; // normal termination

}

#endif
 
A

Alf P. Steinbach

* "Chiller said:
I'm now getting close to finishing my Distance class. In the code below I
have included a number of overload operators that test for equality etc.
I've also added more code in the TEST_DISTANCE driver to test the code.

I now have 2 remaining problems:

1. The code will allow for the input of distances in either cm, m or km
values; however, it isn't smart enough to convert values of different types
(ie cm and km) for correct follow on processing. I would like to add
something to my class that will take any of the three inputs and convert
them to metres for all subsequent operations.

Could someone please give me some examples on how I can achive this.

2. I would also like to include a unary operator- operation which will
return the negative of a Distance value. All my attempts thus far have only
subtracted values. Could someone please advise me on how I must implement
this.

Thanks

.h file
******************************
#ifndef DISTANCE_H

#define DISTANCE_H

#include <iostream>

Don't include anything you don't need in a header file. <iostream> is a very
heavy thing, which a program using your class will perhaps not need.
Presumably you think you need that for your overloaded operator <<, but (1)
you don't need that overload, simply provide a toString function, and (2) if
you find that you need that overload after all, provide it via a separate
header file (which the standard library should have done for e.g. string), and
(3) if you cannot even tolerate a separate header file, at least consider
using the forwarding header instead of the full <iostream> header.


using namespace std;

Whoa! Stop right there! DO NOT, I repeat, DO NOT, put "using namespace
std;" in a header file. That will cause all sorts of problems for client
code, for example client code using a custom class "string".

Uhm, the rest of your code is based on unsound design idea.

Consider instead


class AbstractDistance ...
class Meter: public AbstractDistance ...
class KiloMeter: public AbstractDistance ...
class CentiMeter: public AbstractDistance ...


where AbstractDistance provides the common measure e.g. in meters, but
unknown for client code.
 
J

John Harrison

Chiller said:
I'm now getting close to finishing my Distance class. In the code below I
have included a number of overload operators that test for equality etc.
I've also added more code in the TEST_DISTANCE driver to test the code.

You have some mistakes in the code below. In fact *all* the comparison
operators are wrong.

Consider the following program

int main()
{
Distance one_km(1, km);
Distance one_thousand_m(1000, m);
if (one_km == one_thousand_m)
cout << "1km equals 1000m\n"
else
cout << "1km does not equal 1000m\n"
}

With your code this prints wrongly '1km does not equal 1000m'. You need to
rewrite your operator== so it can handle different units. Same goes for all
the other comparison operators. It's very easy to write simple programs that
show that they calculate the wrong things. I think part of the problem is
that you are asking for too much help from this group and not thinking for
yourself enough. Some times people give you answers without really
understanding what you are trying to achieve and you are just blindly
accepting them.
I now have 2 remaining problems:

1. The code will allow for the input of distances in either cm, m or km
values; however, it isn't smart enough to convert values of different types
(ie cm and km) for correct follow on processing. I would like to add
something to my class that will take any of the three inputs and convert
them to metres for all subsequent operations.

Yes, you should do this for the operator== and all the other operators.

But seriously how hard is this? You know how to convert to meters from
kilometres and centimetres, what's stopping you writing the code?

int Distance::to_metres() const
{
// your code here
}

When you have written this function, you can then use it in operator== etc.
like I explained above.
Could someone please give me some examples on how I can achive this.

I think you are asking for too much help and not learning anything. It is
for your own benefit to try and work out the very simple code required
above.
2. I would also like to include a unary operator- operation which will
return the negative of a Distance value. All my attempts thus far have only
subtracted values. Could someone please advise me on how I must implement
this.

Sounds like you are writing this

Distance Distance::eek:perator-(const Distance& rhs) const

when you should be writing this

Distance Distance::eek:perator-() const

The first is a binary operator-, the second is a unary operator-. But really
the best thing is for you to show us the code you have written.

john
 
J

John Harrison

But seriously how hard is this? You know how to convert to meters from
kilometres and centimetres, what's stopping you writing the code?

int Distance::to_metres() const
{
// your code here
}

Actually that's wrong, because you cannot convert centimetres to a whole
number of metres. This would be possible

double Distance::to_metres() const
{
// your code here
}

but I think it would be much better to use centimetres as your standardised
unit of measure, that way to don't get all the problems of floating point
arithmetic (believe me you'd quickly find out what those were). So try this

int Distance::to_centimetres() const
{
// your code here
}

john
 
N

Nick Hounsome

Chiller said:
I'm now getting close to finishing my Distance class. In the code below I

Please stop creating new threads every tine you tinker with your damn
Distance class
 
C

Chiller

Nick Hounsome said:
I

Please stop creating new threads every tine you tinker with your damn
Distance class

Well thanks for your insight Nick, most helpfull. I'm guessing you've been
reading my threads as well as others just looking for something to say.

For the sake of clarity sometimes it's better to commence a new thread
rather than continue posting new questions to a completed thread.

Why don't you go and watch some TV now!
 
C

Chiller

John Harrison said:
Actually that's wrong, because you cannot convert centimetres to a whole
number of metres. This would be possible

double Distance::to_metres() const
{
// your code here
}

but I think it would be much better to use centimetres as your standardised
unit of measure, that way to don't get all the problems of floating point
arithmetic (believe me you'd quickly find out what those were). So try this

int Distance::to_centimetres() const
{
// your code here
}

john
Thanks John,

I might go and re-think my code. I really only need to perform the
calculations on metres as an input;however, I thought I would try and write
it to allow for cm and km as well. I've only been learning C++ for a couple
of weeks now and my understanding of the large range of associated
operators, functions etc is quite limited. I think I'm trying to do too much
too soon.

Thanks
 
C

Chiller

John,

I've written some code to convert km, m or cm to mm for follow on
processing. I've chosen to convert to mm to allow the int value to remain.
The code is below; however, I don't think it is ideal. When I compile it I
get a message advising that it must return a value. I would simply prefer it
to replace the entered Distance ? (??, km) with a new Distance ? (??, m) so
that it will work with the code I've already written. Could you please have
a look at the code and advise how I can correct it.

I dont want the code to automatically change every entered Distance object
into mm. I would simply like to call to this operation as required by the
comparision functions.

Thanks


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;

}

}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,744
Latest member
CortneyMcK

Latest Threads

Top