help with classes

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

    help with classes

    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<iostre am.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(co nst 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[i]);
    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_vertice s; i++)
    {
    centroid.x += p.verts[i].x;
    centroid.y += p.verts[i].y;
    centroid.z += p.verts[i].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_vertice s-2; i++)
    {
    //use vertex 0 as 'local' origin
    vi1v0 = Subtract(p.vert s[i+1], p.verts[0]);
    vi2v0 = Subtract(p.vert s[i+2], p.verts[0]);
    sum_vector = Add(sum_vector, CrossProduct(vi 1v0, 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_vertice s; i++)
    {
    Display(p.verts[i]);
    if (i != p.num_vertices-1)
    cout << ",";
    }
    cout << endl;
    cout << "polygon edges: ";
    for (int i=0; i<p.num_edges; i++)
    {
    Display(p.edges[i]);
    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_vertic es = 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(centroi d) ; cout << endl;
    cout <<"area of polygon: " << area << endl;

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



  • Allan Bruce

    #2
    Re: help with classes


    "moi" <random1234_NOS PAM_@blueyonder .co.uk> wrote in message
    news:Zs_yb.9532 $VQ5.5059@news-binary.blueyond er.co.uk...[color=blue]
    > hi,
    >
    > im fairly new to c++ and as part of a module at uni im learning it. i[/color]
    know[color=blue]
    > 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.[/color]
    the[color=blue]
    > 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[/color]
    data[color=blue]
    > members with appropriate public access member functions. all previous[/color]
    global[color=blue]
    > 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[/color]
    someone[color=blue]
    > 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<iostre am.h> //c++ I/O[/color]

    should be iostream - note no .h
    [color=blue]
    > #include<conio. h> //getche()[/color]

    non-standard header
    [color=blue]
    > #include<math.h > // sqrt(),...[/color]

    should be cmath
    [color=blue]
    >
    > const int MAX_NO_VERTICES = 25; //max no of polygon vertices and edges.
    > const int MAX_NO_EDGES = 25;[/color]

    why dont you #define these?
    [color=blue]
    >
    > //Data Structures:-
    >
    > //Cartesian point
    > struct Point
    > {
    > double x, y, z; //triple coordinates of a point.
    > };
    >[/color]

    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.


    Comment

    • Chris Theis

      #3
      Re: help with classes


      "Allan Bruce" <allanmb@TAKEAW AYf2s.com> wrote in message
      news:bqi1dr$bit $1@news.freedom 2surf.net...[color=blue]
      >[/color]
      [SNIP][color=blue][color=green]
      > > -----------------------------------
      > > #include<iostre am.h> //c++ I/O[/color]
      >
      > should be iostream - note no .h
      >[color=green]
      > > #include<conio. h> //getche()[/color]
      >
      > non-standard header
      >[color=green]
      > > #include<math.h > // sqrt(),...[/color]
      >
      > should be cmath[/color]

      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.
      [color=blue][color=green]
      > >
      > > const int MAX_NO_VERTICES = 25; //max no of polygon vertices and edges.
      > > const int MAX_NO_EDGES = 25;[/color]
      >
      > why dont you #define these?[/color]

      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!
      [color=blue][color=green]
      > >
      > > //Data Structures:-
      > >
      > > //Cartesian point
      > > struct Point
      > > {
      > > double x, y, z; //triple coordinates of a point.
      > > };
      > >[/color]
      >
      > this would be simply
      > class Point
      > {
      > public:
      > Point();[/color]

      Don't forget to initialize your member variables in the constructor.
      [color=blue]
      > ~Point();[/color]

      I'd suggest to make the dtor virtual as this class might be derived from.
      [color=blue]
      >
      > 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;}[/color]

      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;
      };
      [color=blue]
      >
      > virtual void Display()
      > {std::cout << "(" << p.x << ", " << p.y << ", "
      > << p.z << ")" << std::endl; } // virtual so can be over-ridden[/color]

      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 );
      }
      [color=blue]
      >
      > 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.
      >
      >[/color]

      Regards
      Chris


      Comment

      • Allan Bruce

        #4
        Re: help with classes


        "Chris Theis" <Christian.Thei s@nospam.cern.c h> wrote in message
        news:bqi8oj$ak2 $1@sunnews.cern .ch...[color=blue]
        >
        > "Allan Bruce" <allanmb@TAKEAW AYf2s.com> wrote in message
        > news:bqi1dr$bit $1@news.freedom 2surf.net...[color=green]
        > >[/color]
        > [SNIP][color=green][color=darkred]
        > > > -----------------------------------
        > > > #include<iostre am.h> //c++ I/O[/color]
        > >
        > > should be iostream - note no .h
        > >[color=darkred]
        > > > #include<conio. h> //getche()[/color]
        > >
        > > non-standard header
        > >[color=darkred]
        > > > #include<math.h > // sqrt(),...[/color]
        > >
        > > should be cmath[/color]
        >
        > 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.
        >[color=green][color=darkred]
        > > >
        > > > const int MAX_NO_VERTICES = 25; //max no of polygon vertices and[/color][/color][/color]
        edges.[color=blue][color=green][color=darkred]
        > > > const int MAX_NO_EDGES = 25;[/color]
        > >
        > > why dont you #define these?[/color]
        >
        > 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[/color]
        arise[color=blue]
        > from using this name will give you a very cryptic error because the[/color]
        compiler[color=blue]
        > does not see the symbol MAX_NO_VERTICES anymore but a constant number![/color]

        ok, this will probably be my C side showing through.
        [color=blue]
        >[color=green][color=darkred]
        > > >
        > > > //Data Structures:-
        > > >
        > > > //Cartesian point
        > > > struct Point
        > > > {
        > > > double x, y, z; //triple coordinates of a point.
        > > > };
        > > >[/color]
        > >
        > > this would be simply
        > > class Point
        > > {
        > > public:
        > > Point();[/color]
        >
        > Don't forget to initialize your member variables in the constructor.
        >[color=green]
        > > ~Point();[/color]
        >
        > I'd suggest to make the dtor virtual as this class might be derived from.[/color]

        Of course, sorry OP, i forgot (I am lazy and let VS do this bit for me!)
        [color=blue]
        >[color=green]
        > >
        > > 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[/color][/color]
        to[color=blue][color=green]
        > > denote an input I must set
        > > {*xoX = mX; *xoY = mY; *xoZ = mZ;}[/color]
        >
        > 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;
        > };[/color]

        I suppose, similarly for SetPoint (but not identical obviously)
        [color=blue]
        >[color=green]
        > >
        > > virtual void Display()
        > > {std::cout << "(" << p.x << ", " << p.y << ", "
        > > << p.z << ")" << std::endl; } // virtual so can be over-ridden[/color]
        >
        > Where does p.x, p.y and p.z come from? There is neither an object p nor[/color]
        are[color=blue]
        > there member variables x, y, z in your class. I'd say you should use
        >
        > std::cout << mX << "," << mY << "," << mZ << std::endl;[/color]

        I was being lazy (again) and copied the OP display code (and shoved an
        std::endl on the end). That will serve me right
        [color=blue]
        >
        > In general (but for the OP this might be more than he asks for) I'd[/color]
        suggest[color=blue]
        > 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 );
        > }
        >[color=green]
        > >
        > > protected: // same as private but inherited classes may access directly
        > > double mX, mY, mZ; // i iuse mXXX to specify that this is a[/color][/color]
        member[color=blue][color=green]
        > > variable
        > > };
        > >
        > > This is an example of a very basic class for a point, you can now do[/color][/color]
        some[color=blue][color=green]
        > > work to implement the other classes, using this as a guide.
        > >
        > >[/color]
        >
        > Regards
        > Chris
        >[/color]


        Comment

        • jeffc

          #5
          Re: help with classes


          "moi" <random1234_NOS PAM_@blueyonder .co.uk> wrote in message
          news:Zs_yb.9532 $VQ5.5059@news-binary.blueyond er.co.uk...[color=blue]
          > struct Point
          > {
          > double x, y, z; //triple coordinates of a point.
          > };[/color]

          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;
          };
          [color=blue]
          > //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;
          > }[/color]

          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.
          [color=blue]
          > //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);
          > }[/color]

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


          Comment

          • jeffc

            #6
            Re: help with classes


            "Allan Bruce" <allanmb@TAKEAW AYf2s.com> wrote in message
            news:bqi1dr$bit $1@news.freedom 2surf.net...[color=blue][color=green]
            > >
            > > -----------------------------------
            > > #include<iostre am.h> //c++ I/O[/color]
            >
            > should be iostream - note no .h[/color]

            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.
            [color=blue][color=green]
            > > const int MAX_NO_VERTICES = 25; //max no of polygon vertices and edges.
            > > const int MAX_NO_EDGES = 25;[/color]
            >
            > why dont you #define these?[/color]

            Because const is better.


            Comment

            • John L Fjellstad

              #7
              Re: help with classes

              moi wrote:
              [color=blue]
              > 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().[/color]

              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.
              [color=blue]
              > #include<iostre am.h> //c++ I/O[/color]

              #include <iostream>
              [color=blue]
              > #include<math.h > // sqrt(),...[/color]

              #include <cmath>
              [color=blue]
              > void main()[/color]

              int main()

              --
              John L. Fjellstad

              A: Top posting!
              Q: What is the most irritating thing on Usenet?

              Comment

              Working...