Thread: Class warfare

  1. #1
    Registered User
    Join Date
    Jul 2005
    Posts
    41

    Class warfare

    These classes are published classes, simply I am using them now, but cannot even get them to compile. So for example I get the following errors relating to member functions not being found. I have simplified the code such that one can see the point of failure. Does anyone know what is happening here to cause the failure.

    Code:
    Edge.cpp
    ========
    
    
    #include "Point.h"
    #include "Edge.h"
    
    
    Edge::Edge(Point &_org, Point &_dest) :
     org(_org), dest(_dest)
    {
    }
    
    /*Edge::Edge(void) :
      org(Point(0,0)), org(Point(1,0))
     {
     }
    */
    
    
    Edge &Edge::rot(void)
    {
      Point m; 
      m = 0.5 * (org + dest);
      Point v = dest - org;
      Point n(v.y, -v.x);
      org = m - 0.5 * n;
      dest = m + 0.5 * n;
      return *this;
    }
    
    
    
    Edge.h file
    ========
    
    
    
    class Point;
    
    class Edge {
     public:
       Point org;
       Point dest;
       Edge(Point &_org, Point &_dest);
       Edge(void);
       Edge &rot(void);
       //Edge &flip(void);
       //Point point(double);
       //int intersect(Edge&, double&);
       //int cross(Edge&, double&);
       //bool isVertical(void);
       //double slope(void);
       //double y(double);
     };
    
    
    Point.cpp
    ========
    
    
    
    #include "Point.h"
    
    Point::Point(double _x, double _y):
    x(_x), y(_y)
    {
    }
    
    Point Point::operator+(Point &p)
    {
      return Point(x+p.x, y+p.y);
    }
    
    Point Point::operator-(Point &p)
    {
      return Point(x - p.x, y-p.y);
    }
    
    Point operator*(double s, Point &p)
    {
      return Point(s *p.x, s *p.y);
    }
    
    double Point::operator[](int i)
    {
      return (i ==0) ? x : y;
    }
    
    int Point::operator==(Point &p)
    {
      return (x == p.x) && (y == p.y);
    }
    
    int Point::operator!=(Point &p)
    {
      return !(*this == p);
    }
    
    int Point::operator<(Point &p)
    {
      return ((x < p.x) || ((x == p.x) && (y < p.y)));
    }
    
    int Point::operator>(Point &p)
    {
      return ((x > p.x) || ((x == p.x) && (y > p.y)));
    }
    
    
    /*int main(void)
    {
    
    return (0);
    }*/
    
    
    
    Point.h
    ========
    
    class Point{
    public:
      double x;
      double y;
      Point(double _x = 0.0, double _y = 0.0);
      Point operator+(Point&);
      Point operator-(Point&);
      friend Point operator*(double, Point&);
      double operator[](int);
      int operator==(Point&);
      int operator!=(Point&);
      int operator<(Point&);
      int operator>(Point&);
      int classify(Point&, Point&);
      //int classify(Edge&);
      double polarAngle(void);
      double length(void);
      //double distance(Edge&);
    };
    
    Error on compilation.
    ============
    
    g++ -c Edge.cpp -o Edge.o
    Edge.cpp: In member function ‘Edge& Edge::rot()’:
    Edge.cpp:20: error: no match for ‘operator*’ in ‘5.0e-1 * ((Edge*)this)->Edge:rg. Point:perator+(((Point&)(&((Edge*)this)->Edge::dest)))’
    Point.h:10: note: candidates are: Point operator*(double, Point&)
    Edge.cpp:23: error: no match for ‘operator-’ in ‘m - operator*(5.0e-1, ((Point&)(& n)))’
    Point.h:9: note: candidates are: Point Point:perator-(Point&)
    Edge.cpp:24: error: no match for ‘operator+’ in ‘m + operator*(5.0e-1, ((Point&)(& n)))’
    Point.h:8: note: candidates are: Point Point:perator+(Point&)
    Code:
    The Makefile is as follows:
    
    
    all: Poly
    	
    Poly:    Point.o Edge.o Polygons.o 
    
    	g++  -o Poly Point.o Edge.o Polygons.o
    
    Point.o: Point.cpp
    	g++    -c Point.cpp -o Point.o	
    
    Edge.o: Edge.cpp
    	g++    -c Edge.cpp -o Edge.o	
    	
    Polygons.o: Polygons.cpp
    	g++    -c Polygons.cpp -o Polygons.o
    
    clean:
    	find . -name '*.o' | xargs rm -f ;

    Thanks

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Your operator functions should take a const reference (or be called by value), otherwise you can't pass temporary values into the operator. So for example:
    Code:
      Point operator+(const Point&);
      Point operator-(const Point&);
      friend Point operator*(double, const Point&);
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> m = 0.5 * (org + dest);

    The result of (org + dest) is a temporary object. Some compilers may allow passing it to a function that takes a non-const reference as an extension (or a bug), and that is probably why the classes were published.

  4. #4
    Registered User
    Join Date
    Apr 2008
    Posts
    890
    Quote Originally Posted by Daved View Post
    >> m = 0.5 * (org + dest);

    The result of (org + dest) is a temporary object. Some compilers may allow passing it to a function that takes a non-const reference as an extension (or a bug), and that is probably why the classes were published.
    It indeed works on VC++ 6.0...

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    So, as a conclusion, the published code is either not tested with a modern compiler, or written a while ago. Use with new compiler will require adding const.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> Use with new compiler will require adding const.

    It actually works with VC++ 2005 as well. It's probably more accurate to say that if you want it to be standards conforming (and therefore more portable) then it requires the const.

  7. #7
    Registered User
    Join Date
    Apr 2008
    Posts
    890
    Also, to the OP, a common approach is to make operator+= a member, and operator+ a friend that is implemented in terms of +=:

    Code:
    Foo & operator+=(const Foo & rhs) { ... ; return *this; }
    friend Foo operator+(const Foo & lhs, const Foo & rhs)
    {
        Foo result = lhs;
        result += rhs;
    
        return result;
    }

  8. #8
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    don't class members that are forwardly-declared types have to be pointers?

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by m37h0d View Post
    don't class members that are forwardly-declared types have to be pointers?
    Sort of. As long as the compiler doesn't need to know the size or content, it's fine to forward declare classes. This means that you can, realistically, use forward declared classes as either pointers or references, but not much else.

    Edit: Oh, and I think forward declared classes can be used as parameters to function prototypes, even if they are not reference/pointer paramters.

    --
    Mats
    Last edited by matsp; 04-22-2008 at 09:14 AM.
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> don't class members that are forwardly-declared types have to be pointers?
    In this case it probably only "works" because Point.h is #include'd before Edge.h which means the forward declaration is ignored.

    You are right that Edge.h should #include "Point.h" here, since Edge has Point members and the compiler needs to know how big the Point is to know the size of Edge. If the #include order changes the build would break.

  11. #11
    Registered User
    Join Date
    Apr 2008
    Posts
    890
    Also, I don't know if they were omitted for brevity, but I noticed there are no include file guards in the headers posted.

  12. #12
    Registered User
    Join Date
    Jul 2005
    Posts
    41
    Great, thats the ticket!

    Thanks for that, now for my next question...got the following class:

    Code:
    class Vertex : public Node, public Point {
    public:
      Vertex(double x, double y);
      Vertex(const Point&);
      Vertex *cw(void);
      Vertex *ccw(void);
      Vertex *neighbor(int rotation);
      Point point(void);
      Vertex *insert(const Vertex*);
      Vertex *remove(void);
      void splice(const Vertex*);
      Vertex *split(const Vertex*);
      friend class Polygon;
    };
    However I am getting the following error:

    Vertex.h:3: error: expected class-name before ‘,’ token

    Which is referring to the line "class Vertex : public Node, public Point"

    Now all the classes have hopefully been defined correctly....

    Any idea why this is failing?? Again it should be standard code, but does not compile...

    Thanks

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Post the smallest and simplest program that demonstrates the problem.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  14. #14
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by disruptivetech View Post
    Great, thats the ticket!

    Thanks for that, now for my next question...got the following class:

    Code:
    class Vertex : public Node, public Point {
    public:
      Vertex(double x, double y);
      Vertex(const Point&);
      Vertex *cw(void);
      Vertex *ccw(void);
      Vertex *neighbor(int rotation);
      Point point(void);
      Vertex *insert(const Vertex*);
      Vertex *remove(void);
      void splice(const Vertex*);
      Vertex *split(const Vertex*);
      friend class Polygon;
    };
    However I am getting the following error:

    Vertex.h:3: error: expected class-name before ‘,’ token

    Which is referring to the line "class Vertex : public Node, public Point"

    Now all the classes have hopefully been defined correctly....

    Any idea why this is failing?? Again it should be standard code, but does not compile...

    Thanks
    You need to make sure that Node and point are declared before you declare Vertex. This probably means that you need to include Point.h and Node.h at the top of Vertex.h.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Class design problem
    By h3ro in forum C++ Programming
    Replies: 10
    Last Post: 12-19-2008, 09:10 AM
  2. Specializing class
    By Elysia in forum C++ Programming
    Replies: 6
    Last Post: 09-28-2008, 04:30 AM
  3. Defining derivated class problem
    By mikahell in forum C++ Programming
    Replies: 9
    Last Post: 08-22-2007, 02:46 PM
  4. matrix class
    By shuo in forum C++ Programming
    Replies: 2
    Last Post: 07-13-2007, 01:03 AM