help with classes

M

moi

hi,

im fairly new to c++ and as part of a module at uni im learning it. i know
the basics i suppose, but as our final hand-in we have to alter code we
wrote for an earlier assignment to use classes as opposed to structures. the
program basically modelled a simple polygon using point, line and polyogon
structures. and had various functions to find the properties of the shape
such as area, perimeter, etc.

the question reads along the lines of:-
rewrite the data structures as classes and assign private access to all data
members with appropriate public access member functions. all previous global
functions must now be redesigned as member functions of the corresponding
classes, thus the following member functions must be supported:
point: distance(), display()
line: length(), display()
polygon: area(), centroid(), perimeter(), display().

i have copied and pasted my code below. obviously im not looking for someone
to do my work for me (man, that would be nice) but i could really use a
nudge in the right direction, and a bit of a foothold to get started from.

thanks,

M.o'N

-----------------------------------
#include<iostream.h> //c++ I/O
#include<conio.h> //getche()
#include<math.h> // sqrt(),...

const int MAX_NO_VERTICES = 25; //max no of polygon vertices and edges.
const int MAX_NO_EDGES = 25;

//Data Structures:-

//Cartesian point
struct Point
{
double x, y, z; //triple coordinates of a point.
};

//Straight line segment
struct Line
{
Point p1, p2; //two end points of a line
};

//Polygon with Point vertices and Line straight-line edges.
struct Polygon
{
int num_vertices, num_edges; //number of vertices and edges.
Point verts[MAX_NO_VERTICES]; //polygon vertices
Line edges[MAX_NO_EDGES]; //polygon edges
};

//3D vector
struct Vector3D
{
double a, b, c; //vector components
};

//adds two Vector3D objects
Vector3D Add(const Vector3D& u, const Vector3D& v)
{
Vector3D add;
add.a = u.a + v.a;
add.b = u.b + v.b;
add.c = u.c + v.c;
return add;
}

//returns the cross product of two vectors (right-hand screw rule)
// UxV = [(UyVz-UzVy), (UzVx-UxVz), (UxVy-UyVx)]
Vector3D CrossProduct(const Vector3D& u, const Vector3D& v)
{
Vector3D cross;
cross.a = u.b*v.c - u.c*v.b;
cross.b = u.c*v.a - u.a*v.c;
cross.c = u.a*v.b - u.b*v.a;
return cross;
}

//returns the norm or magnitued (i.e. lenght) of a vector
double Norm (const Vector3D& v)
{return sqrt(v.a*v.a + v.b*v.b + v.c*v.c);}

//Point functions:

//returns the distance between 2 points
double Distance(const Point& p1, const Point& p2)
{
double x = p2.x-p1.x;
double y = p2.y-p1.y;
double z = p2.z-p1.z;
return sqrt(x*x + y*y + z*z);
}

//retunrs v=p-q, ie a Vector3D object
Vector3D Subtract(const Point& p, const Point& q)
{
Vector3D v;
v.a = p.x - q.x;
v.b = p.y - q.y;
v.c = p.z - q.z;
return v;
}

//o/p a point
void Display(const Point& p)
{ cout << "(" << p.x << ", " << p.y << ", " << p.z << ")" ; }

//Line functions:

//returns the length of a Line
double Length(const Line& l)
{ return Distance(l.p1, l.p2);}

//o/p a line
void Display(const Line& l)
{cout << "["; Display(l.p1) ; cout << ", " ; Display(l.p2) ; cout << "]" ;}

//polygon functions

//returns the perimeter of a polygon
double Perimeter(const Polygon& p)
{
double perimeter(0.0);
for (int i = 0; i<p.num_edges; i++)
perimeter += Length(p.edges);
return perimeter;
}

//returns the centroid of a polygon (uses averaging of vertices)
Point Centroid(const Polygon& p)
{
Point centroid = {0.0,0.0,0.0};
for (int i=0; i<p.num_vertices; i++)
{
centroid.x += p.verts.x;
centroid.y += p.verts.y;
centroid.z += p.verts.z;
}
centroid.x /= p.num_vertices;
centroid.y /= p.num_vertices;
centroid.z /= p.num_vertices;
return centroid;
}

//returns the area of a polygon (uses the cross-product rule)
double Area(const Polygon& p)
{
Vector3D vi1v0, vi2v0, sum_vector;
for (int i=0; i<p.num_vertices-2; i++)
{
//use vertex 0 as 'local' origin
vi1v0 = Subtract(p.verts[i+1], p.verts[0]);
vi2v0 = Subtract(p.verts[i+2], p.verts[0]);
sum_vector = Add(sum_vector, CrossProduct(vi1v0, vi2v0));
}
return Norm(sum_vector)/2.0;
}

//o/p a polygon
void Display(const Polygon& p)
{
cout << "polygon vertices: ";
for (int i=0; i<p.num_vertices; i++)
{
Display(p.verts);
if (i != p.num_vertices-1)
cout << ",";
}
cout << endl;
cout << "polygon edges: ";
for (int i=0; i<p.num_edges; i++)
{
Display(p.edges);
if (i != p.num_edges-1)
cout << ",";
}
}

void main()
{
//define a polygon [triangle in this instance]
Polygon poly;

//set poly's number of vertices and edges
poly.num_vertices = 3;
poly.num_edges = 3;

//vertices
poly.verts[0].x = 1.0 ; poly.verts[0].y = 1.0 ; poly.verts[0].z = 0.0;
poly.verts[1].x = 4.0 ; poly.verts[1].y = 1.0 ; poly.verts[1].z = 0.0;
poly.verts[2].x = 2.0 ; poly.verts[2].y = 3.0 ; poly.verts[2].z = 0.0;

//edges
poly.edges[0].p1 = poly.verts[0] ; poly.edges[0].p2 = poly.verts[1];
poly.edges[1].p1 = poly.verts[1] ; poly.edges[1].p2 = poly.verts[2];
poly.edges[2].p1 = poly.verts[2] ; poly.edges[2].p2 = poly.verts[0];

//properties
double perimeter = Perimeter(poly);
Point centroid = Centroid(poly);
double area = Area(poly);

//o/p
cout << "polygon: " <<endl;
Display(poly) ; cout << endl;
cout << "perimeter of polygon: " << perimeter << endl;
cout << "centroid of polygon: ";
Display(centroid) ; cout << endl;
cout <<"area of polygon: " << area << endl;

cout << "press any key to continue...";
getche();
}
 
A

Allan Bruce

moi said:
hi,

im fairly new to c++ and as part of a module at uni im learning it. i know
the basics i suppose, but as our final hand-in we have to alter code we
wrote for an earlier assignment to use classes as opposed to structures. the
program basically modelled a simple polygon using point, line and polyogon
structures. and had various functions to find the properties of the shape
such as area, perimeter, etc.

the question reads along the lines of:-
rewrite the data structures as classes and assign private access to all data
members with appropriate public access member functions. all previous global
functions must now be redesigned as member functions of the corresponding
classes, thus the following member functions must be supported:
point: distance(), display()
line: length(), display()
polygon: area(), centroid(), perimeter(), display().

i have copied and pasted my code below. obviously im not looking for someone
to do my work for me (man, that would be nice) but i could really use a
nudge in the right direction, and a bit of a foothold to get started from.

thanks,

M.o'N

should be iostream - note no .h
#include<conio.h> //getche()

non-standard header
#include<math.h> // sqrt(),...

should be cmath
const int MAX_NO_VERTICES = 25; //max no of polygon vertices and edges.
const int MAX_NO_EDGES = 25;

why dont you #define these?
//Data Structures:-

//Cartesian point
struct Point
{
double x, y, z; //triple coordinates of a point.
};

this would be simply
class Point
{
public:
Point();
~Point();

void SetPoint(double xiX, double xiY, double xiZ) // i use xiXXX to
denote a valid input var
{mX = xiX; mY = xiY; mZ = xiZ;} // inline member function

void GetPoint(double *xoX, double *xoY, double *xoZ) // i use xoXXX to
denote an input I must set
{*xoX = mX; *xoY = mY; *xoZ = mZ;}

virtual void Display()
{std::cout << "(" << p.x << ", " << p.y << ", "
<< p.z << ")" << std::endl; } // virtual so can be over-ridden


protected: // same as private but inherited classes may access directly
double mX, mY, mZ; // i iuse mXXX to specify that this is a member
variable
};

This is an example of a very basic class for a point, you can now do some
work to implement the other classes, using this as a guide.
 
C

Chris Theis

Allan Bruce said:
[SNIP]
should be iostream - note no .h
#include<conio.h> //getche()

non-standard header
#include<math.h> // sqrt(),...

should be cmath

If you use the standard headers (which is of course recommended) don't
forget a using statement or add the std:: to the classes from standard
namespace.
why dont you #define these?

Because #defines are a bad thing. If you use #define MAX_NO_VERTICES then
the preprocssor will go ahead and remove MAX_NO_VERTICES from the code
replacing it with the defined value. Therefore any problems that might arise
from using this name will give you a very cryptic error because the compiler
does not see the symbol MAX_NO_VERTICES anymore but a constant number!
this would be simply
class Point
{
public:
Point();

Don't forget to initialize your member variables in the constructor.
~Point();

I'd suggest to make the dtor virtual as this class might be derived from.
void SetPoint(double xiX, double xiY, double xiZ) // i use xiXXX to
denote a valid input var
{mX = xiX; mY = xiY; mZ = xiZ;} // inline member function

void GetPoint(double *xoX, double *xoY, double *xoZ) // i use xoXXX to
denote an input I must set
{*xoX = mX; *xoY = mY; *xoZ = mZ;}

For access functions it's quite a good and common practice to declare the
function as const:

void GetPoint(double& xoX, double& xoY, double& xoZ) const {
xoX = mX; xoY = mY; xoZ = mZ;
};
virtual void Display()
{std::cout << "(" << p.x << ", " << p.y << ", "
<< p.z << ")" << std::endl; } // virtual so can be over-ridden

Where does p.x, p.y and p.z come from? There is neither an object p nor are
there member variables x, y, z in your class. I'd say you should use

std::cout << mX << "," << mY << "," << mZ << std::endl;

In general (but for the OP this might be more than he asks for) I'd suggest
to implement a virtual display function which receives a reference to a
ostream and is called by overloaded version of operator <<.

For example:

virtual ostream& Display( ostream& os ) {
return os << mX << "," << mY << "," << mZ;
}

friend ostream& operator<<( ostream& os, Point& rhs ) {
return rhs.Display( os );
}
protected: // same as private but inherited classes may access directly
double mX, mY, mZ; // i iuse mXXX to specify that this is a member
variable
};

This is an example of a very basic class for a point, you can now do some
work to implement the other classes, using this as a guide.

Regards
Chris
 
A

Allan Bruce

Chris Theis said:
Allan Bruce said:
[SNIP]
should be iostream - note no .h
#include<conio.h> //getche()

non-standard header
#include<math.h> // sqrt(),...

should be cmath

If you use the standard headers (which is of course recommended) don't
forget a using statement or add the std:: to the classes from standard
namespace.
why dont you #define these?

Because #defines are a bad thing. If you use #define MAX_NO_VERTICES then
the preprocssor will go ahead and remove MAX_NO_VERTICES from the code
replacing it with the defined value. Therefore any problems that might arise
from using this name will give you a very cryptic error because the compiler
does not see the symbol MAX_NO_VERTICES anymore but a constant number!

ok, this will probably be my C side showing through.
Don't forget to initialize your member variables in the constructor.


I'd suggest to make the dtor virtual as this class might be derived from.

Of course, sorry OP, i forgot (I am lazy and let VS do this bit for me!)
For access functions it's quite a good and common practice to declare the
function as const:

void GetPoint(double& xoX, double& xoY, double& xoZ) const {
xoX = mX; xoY = mY; xoZ = mZ;
};

I suppose, similarly for SetPoint (but not identical obviously)
Where does p.x, p.y and p.z come from? There is neither an object p nor are
there member variables x, y, z in your class. I'd say you should use

std::cout << mX << "," << mY << "," << mZ << std::endl;

I was being lazy (again) and copied the OP display code (and shoved an
std::endl on the end). That will serve me right
 
J

jeffc

moi said:
struct Point
{
double x, y, z; //triple coordinates of a point.
};

With structs the default access is public. I suggest you make that explicit
in your code. For example,
struct Point
{
public:
double x, y, z;
};

And with classes
class Point
{
private:
double x, y, z;
};
//3D vector
struct Vector3D
{
double a, b, c; //vector components
};

//adds two Vector3D objects
Vector3D Add(const Vector3D& u, const Vector3D& v)
{
Vector3D add;
add.a = u.a + v.a;
add.b = u.b + v.b;
add.c = u.c + v.c;
return add;
}

This function needs to get moved inside the brackets of the Vector3D
struct/class, and it should be in a public section, not private. The trick
then will be to figure out the parameters. You will no longer need 2
parameters, because you will already be INSIDE the object that is one of the
parameters. Alternatively, this could be a static function that still
requires the use of 2 parameters. You will have to ask your instructor this
question.
//Point functions:

//returns the distance between 2 points
double Distance(const Point& p1, const Point& p2)
{
double x = p2.x-p1.x;
double y = p2.y-p1.y;
double z = p2.z-p1.z;
return sqrt(x*x + y*y + z*z);
}

This goes inside the Point class, with the same comments.
 
J

jeffc

Allan Bruce said:
should be iostream - note no .h

This depends on his compiler. I'd say this is most likely already working
code for him, since he has to change it for this assignment.
why dont you #define these?

Because const is better.
 
J

John L Fjellstad

moi said:
the question reads along the lines of:-
rewrite the data structures as classes and assign private access to all
data members with appropriate public access member functions. all previous
global functions must now be redesigned as member functions of the
corresponding classes, thus the following member functions must be
supported: point: distance(), display()
line: length(), display()
polygon: area(), centroid(), perimeter(), display().

You basically do what they ask you to here. Make all your structs to
classes, make all the freestanding functions to public member functions,
make all the variables private.
#include<iostream.h> //c++ I/O

#include said:
#include<math.h> // sqrt(),...

#include said:
void main()

int main()
 

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

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,818
Latest member
Brigette36

Latest Threads

Top