Class problem

C

Chiller

Ok, this is a continuation of a problem I posted on an earlier thread. I've
started another thread because my problem has progressed from the initial
constructor problem into a general method problem.

I'm trying to write a class (Distance.h & Distance.cpp) that will perform
operations on distances. ie compare, add, subtract etc distance values.

I'm still in the early stages of developing the class; however, I'm stuck
with how best to enter the values. The class needs to accept a number value
and a unit of measure (cm, m or km). This should be input as
Distance a (5, m);
Distance b (8, km); etc

What I've written so far will accept the values; however, when I output the
values to screen I don't get the display I'm looking for. I realise this is
because of the way I've used "enum"; however, I'm not sure on how to use it
correctly. The input is given at the botom of the Distance.cpp file under
TEST_DISTANCE, this is a test driver that will need to be declared in the
preprocessor to be able to complile correctly.

I'd greatly appreciate any advice on where I'm going wrong and how to
fix/improve what I've written. I'm still very much learning so I'd
appreciate clear and simple explanations and examples of how to make this
work.

The code is as follows:

Thanks


Distance.h

************************************
#ifndef DISTANCE_H

#define DISTANCE_H

#include <iostream>

using namespace std;

class Distance

{

public :

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

Distance (int) ; // constructor - takes int value

Distance (void) ; // default - zero

//access member functions

int number (void) const;

int measure (void) const;


private :

int nu ; // the value

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

} ;

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

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

#endif



Distance.cpp as follows:

*****************************************

#include "Distance.h"

#include <iostream>

using namespace std;

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

| implementation of member functions |

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

// constructor

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

Distance :: Distance (int n) : nu(n) {}

Distance :: Distance (void) : nu(0) {}



enum

{

m,

km,

};



// access functions

int Distance :: number (void) const

{

return nu;

}

int Distance :: measure (void) const

{

return me;

}

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

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

{

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

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

Distance b (4);

Distance c (2);

Distance d;

Distance e (5, m);


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



cin.ignore();

return 0; // normal termination

}

#endif
 
N

Nick Hounsome

Chiller said:
Ok, this is a continuation of a problem I posted on an earlier thread. I've
started another thread because my problem has progressed from the initial
constructor problem into a general method problem.

I'm trying to write a class (Distance.h & Distance.cpp) that will perform
operations on distances. ie compare, add, subtract etc distance values.

I'm still in the early stages of developing the class; however, I'm stuck
with how best to enter the values. The class needs to accept a number value
and a unit of measure (cm, m or km). This should be input as
Distance a (5, m);
Distance b (8, km); etc

What I've written so far will accept the values; however, when I output the
values to screen I don't get the display I'm looking for. I realise this is
because of the way I've used "enum"; however, I'm not sure on how to use it
correctly. The input is given at the botom of the Distance.cpp file under
TEST_DISTANCE, this is a test driver that will need to be declared in the
preprocessor to be able to complile correctly.

I'd greatly appreciate any advice on where I'm going wrong and how to
fix/improve what I've written. I'm still very much learning so I'd
appreciate clear and simple explanations and examples of how to make this
work.

The code is as follows:

Thanks


Distance.h

************************************
#ifndef DISTANCE_H

#define DISTANCE_H

#include <iostream>

using namespace std;

class Distance

{

public :

enum Unit { m,km };
Distance (int, int) ; // constructor - takes int values

Distance(size_t distance, Unit unit);
Distance (int) ; // constructor - takes int value

Is this supposed to default the distance or the unit?
Use enum for unit.
Distance (void) ; // default - zero

What unit?
//access member functions

int number (void) const;

int measure (void) const;


private :

int nu ; // the value

size_t nu;
int me ; // the unit of measure (m)

Unit me;
} ;

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

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

and
ostream& operator<<(ostream&,const Distance::Unit&); // output lookup of
string
istream& operator>>(istream&,const Distance::Unit&); // read string and
lookup value
istream& operator>>(istream&,const Distance&); // use above func


It seems unlikely to me that you actually want dynamic units.
I suggest that you fix and document the units and handle unit conversion
only on input.
If you really want different units internally as well a sexternally then
consider a template class
parameterized by the enum.
 
J

John Harrison

Chiller said:
Ok, this is a continuation of a problem I posted on an earlier thread. I've
started another thread because my problem has progressed from the initial
constructor problem into a general method problem.

I'm trying to write a class (Distance.h & Distance.cpp) that will perform
operations on distances. ie compare, add, subtract etc distance values.

I'm still in the early stages of developing the class; however, I'm stuck
with how best to enter the values. The class needs to accept a number value
and a unit of measure (cm, m or km). This should be input as
Distance a (5, m);
Distance b (8, km); etc

What I've written so far will accept the values; however, when I output the
values to screen I don't get the display I'm looking for. I realise this is
because of the way I've used "enum"; however, I'm not sure on how to use it
correctly.

I think the answer I gave earlier works, was there a problem with it?

In any case see below.

[snip]
enum

{

m,

km,

};



// access functions

int Distance :: number (void) const

{

return nu;

}

int Distance :: measure (void) const

{

return me;

}

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

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

{

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

Replace above line with this

out << "(" << d.number() << ",";
switch (d.measure())
{
case m:
out << "m";
break;
case km:
out << "km";
break;
}
out << ")";
return out;

}

It's pretty simple, I think maybe you are looking for a more automatic
solution which doesn't exist.

Also have a look at my earlier post for a slightly more elegant solution.

john
 
C

Chiller

John,

Thanks again, I included your code in the incorrect spot earlier so it
didn't compile correctly. It now compiles and outputs correctly.

My next step is to add an overload of "operator=" assignment operator to
allow one Distance value to be assigned to another.

I've added the code to both the .h and .cpp files to allow this. It compiles
and runs; however, the output shows that the assignment of values seems to
occur before the original values have been displayed. Could you please have
a look and advise where I'm going wrong and how I can correct the problem.

Thanks


..h file as follows:
************************************
#ifndef DISTANCE_H

#define DISTANCE_H

#include <iostream>

using namespace std;

class Distance

{

public :

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

Distance (void) ; // default - zero

//access member functions

int number (void) const;

int measure (void) const;

//overloads

Distance operator= (Distance) ; // overload of assignment operator



private :

int nu ; // the value

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

} ;

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

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

#endif


..cpp file as follows:
************************************

#include "Distance.h"

#include <iostream>

using namespace std;

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

| implementation of member functions |

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

// constructors

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

Distance :: Distance (void) : nu(0) {}

enum {cm, m, km};

// access functions

int Distance :: number (void) const

{

return nu;

}

int Distance :: measure (void) const

{

return me;

}

// Overload of the "=" operator

Distance Distance :: operator= (Distance right_operand)

{

return Distance ( nu = right_operand.nu, me = right_operand.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;

cin.ignore();

return 0; // normal termination

}

#endif
 
J

John Harrison

Chiller said:
John,

Thanks again, I included your code in the incorrect spot earlier so it
didn't compile correctly. It now compiles and outputs correctly.

My next step is to add an overload of "operator=" assignment operator to
allow one Distance value to be assigned to another.

There's no need to do that. You only need to do write an operator= if the
default one isn't correct. In your case the default assignment operator will
work fine.

For the record however here's how you should define operator=

Distance& Distance :: operator= (const Distance& right_operand)
{
nu = right_operand.nu;
me = right_operand.me;
return *this;
}

But as I said, you don't need to do this, just remove all traces of
operator= from your code and you'll find that you can still assign one
Distance value to another perfectly well.

john
 
D

Daniel T.

Chiller said:
Ok, this is a continuation of a problem I posted on an earlier thread. I've
started another thread because my problem has progressed from the initial
constructor problem into a general method problem.

I'm trying to write a class (Distance.h & Distance.cpp) that will perform
operations on distances. ie compare, add, subtract etc distance values.

I'm still in the early stages of developing the class; however, I'm stuck
with how best to enter the values. The class needs to accept a number value
and a unit of measure (cm, m or km). This should be input as
Distance a (5, m);
Distance b (8, km); etc

I don't think the above is such a good idea. It requires a global enum {
m, km }; which would cause problems with any use of those 1 and 2
character identifiers elsewhere in a program. Another important point, I
think your class should be able to handle decemal point input (5.4, 8.7
and such.)

Better would be to put the enum inside the Distance class, so the input
would be:

Distance a(5.3, Distance::m);
Distance b(8.7, Distance::km);

I'd hate to say it, but I think you should throw out what you have so
far and start over.

Start with this main as a test case:

----------------------------------------------------------------------
#include "Distance.h"
#include <string>
#include <sstream>
#include <iostream>

template < typename T >
void check( const T& expected, const T& got )
{
if ( expected != got ) {
std::cerr << "Expected: '" << expected
<< "' got: '" << got << "'" << std::endl;
abort();
}
}

int main()
{
using namespace std;
Distance a(5.3, Distance::m);
Distance b(8.7, Distance::km);
ostringstream oss;
oss << a;
check( string( "5.3m" ), oss.str() );
oss.str( "" );
oss << b;
check( string( "8.7km" ), oss.str() );

cout << "OK";
}
----------------------------------------------------------------------

Just plug this into your compiler and try to compile it. Fix the first
error and try again, keep doing this until you get no compile time
errors. Then the code will run, but you will see the "Expected: got:"
error show up on the screen. Keep fixing it until the only thing that
outputs is "OK".

Once you get it to that point, post what you have and request help, and
I'll provide you with another test.

(For right now, don't worry about how the test above works, just accept
that it does, you can study it later when you know more about C++.)
 

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

Members online

Forum statistics

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

Latest Threads

Top