Thread: Header files and classes

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

    Header files and classes

    Hi

    I have a couple of classes defined, one class and structures defined that are from another class. So I have for example:

    Code:
    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);
     };
    and Point is thus defined:

    Code:
    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&);
    };
    In terms of construction, I have placed the class constructs in Point.h and Edge.h with the member functions in Point.cpp and Edge.cpp. I then have a file called Polygons.cpp which includes the header files. However when I try and make with the following makefile, I dont get anything:

    Code:
    all: Poly
    	
    Poly:    Point.o Edge.o Polygons.o 
    
    	g++ -O4  -o Poly Point.o Edge.o Polygons.o
    
    Point.o: Point.cpp
    	g++ -O4   -c  -Wno-deprecated  -Wall   Point.cpp -o Point.o	
    
    Edge.o: Edge.cpp
    	g++ -O4   -c  -Wno-deprecated  -Wall   Edge.cpp -o Edge.o	
    	
    Polygons.o: Polygons.cpp
    	g++  -O4  -c  -Wno-deprecated  -Wall   Polygons.cpp -o Polygons.o
    
    clean:
    	find . -name '*.o' | xargs rm -f ;
    I find the following errors:

    Edge.h:8: error: ‘Point’ does not name a type
    Edge.h:9: error: ‘Point’ does not name a type
    Edge.h:10: error: expected `)' before ‘&’ token
    Edge.h:14: error: ‘Point’ does not name a type

    BTW, a typical .h function looks like this:

    Code:
    #ifndef _Edge_h
    #define _Edge_h
    
    #include "Point.h"
    
    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);
     };
    
    // 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 = 0.5 * (org + dest);
    //   Point v = dest - org;
    //   Point n(n.y, -v.x);
    //   org = m - 0.5 *n;
    //   dest = m + 0.5 *n;
    //   return *this;
    // }
    // 
    // Edge &Edge::flip(void)
    // {
    //   return rot().rot();
    // }
    // 
    // Point Edge::point(double t)
    // {
    //   return Point(org + t * (dest - org));
    // }
    // 
    // enum { COLLINEAR, PARALLEL, SKEW, SKEW_CROSS, SKEW_NO_CROSS};
    // 
    // double dotProduct(Point &p, Point &q)
    // {
    //   return (p.x * q.x + p.y *q.y);
    // }
    // 
    // int Edge::intersect(Edge &e, double &t)
    // {
    //   Point a = org;
    //   Point b = dest;
    //   Point c = e.org;
    //   Point d = e.dest;
    //   Point n = Point((d-c).y, (c-d).x);
    //   double denom = dotProduct(n, b-a);
    //   if (denom == 0.0) 
    //   {
    //     int aclass = org.classify(e);
    //     if ((aclass==LEFT) || (aclass==RIGHT))
    //      return PARALLEL;
    //     else
    //      return COLLINEAR;
    //   }
    //   double num = dotProduct(n, a-c);
    //   t=-num/denom;
    //   return SKEW;
    // }
    #endif
    How should I best construct these sort of classes???

    Thanks

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    They're referring to each other, but thankfully they are using references. You can put "class Edge;" or "class Point;" in the headers before the respective classes (best use one) to make it work.
    The compiler must know another type before it parses it, so it must, for example, know Point before you use it. So Point must be defined before Edge. But if Edge also uses Point, then you must tell the compiler the type exists, but not necessarily define it (only need to if using it, so include it in the implementation).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
    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&);
    };
    It looks to me like you need to include Edge.h before class Point - is that what you are doing?

    If so, you need to forward declare the second class, then define the first class itself. Something like this:
    Code:
    class Point;
    #include "Edge.h"
    
    class Point 
    {
    ...
    };
    As long as the declaration of class Edge doesn't contain code that actually needs to see inside the Point class until the Edge class has been declared.

    A few other points:
    1. Don't use filenames like "Edge.h" and "Point.h" - use lower-case only names, that will be much more convenient for portability.

    2. Give names of variables in the declaration of member functions, e.g.:
    [code]
    Class Edge {
    ...
    intersect(Edge &e, double &t);
    };

    It's not so important in these classes, but knowing the names of arguments in a function when looking at the class interface is really helpful, so it's a good habit.

    --
    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.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    A little off topic, but...
    • You might want to declare member variables private so as to have more control over the implementation.
    • You might want to make your class const correct: logically, a member function like isVertical() can be called with a const Edge object, but at the moment that is not possible.
    • You might want to make operator== and the other comparison operators free functions instead, friends of Point if necessary (or you should implement a compare() member function that returns 0 if for equality, a positive integer if the first point object is greater than the second, and a negative integer otherwise, then implement the comparison operators in terms of compare()). If not, they should be const member functions. They should take the Point objects to compare by const reference, since it is logical to be able to compare const Point objects. They should also return a bool.
    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

  5. #5
    Registered User
    Join Date
    Jul 2005
    Posts
    41
    Quote Originally Posted by Elysia View Post
    They're referring to each other, but thankfully they are using references. You can put "class Edge;" or "class Point;" in the headers before the respective classes (best use one) to make it work.
    The compiler must know another type before it parses it, so it must, for example, know Point before you use it. So Point must be defined before Edge. But if Edge also uses Point, then you must tell the compiler the type exists, but not necessarily define it (only need to if using it, so include it in the implementation).
    I have placed class Point; in the appropriate header file. However I find that now when compiling I get the following string of errors:

    Edge.cpp: In member function ‘Edge& Edge::rot()’:
    Edge.cpp:19: 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:22: 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:23: error: no match for ‘operator+’ in ‘m + operator*(5.0e-1, ((Point&)(& n)))’
    Point.h:8: note: candidates are: Point Point:perator+(Point&)
    Edge.cpp: In member function ‘Point Edge:oint(double)’:
    Edge.cpp:34: error: no match for ‘operator*’ in ‘t * ((Edge*)this)->Edge::dest. Point:perator-(((Point&)(&((Edge*)this)->Edge:rg)))’
    Point.h:10: note: candidates are: Point operator*(double, Point&)
    Edge.cpp: In member function ‘int Edge::intersect(Edge&, double&)’:
    Edge.cpp:51: error: invalid initialisation of non-const reference of type ‘Point&’ from a temporary of type ‘Point’
    Edge.cpp:39: error: in passing argument 2 of ‘double dotProduct(Point&, Point&)’
    Edge.cpp:54: error: no matching function for call to ‘Point::classify(Edge&)’
    Point.h:16: note: candidates are: int Point::classify(Point&, Point&)
    Edge.cpp:55: error: ‘LEFT’ was not declared in this scope
    Edge.cpp:55: error: ‘RIGHT’ was not declared in this scope
    Edge.cpp:60: error: invalid initialisation of non-const reference of type ‘Point&’ from a temporary of type ‘Point’
    Edge.cpp:39: error: in passing argument 2 of ‘double dotProduct(Point&, Point&)’
    make: *** [Edge.o] Error 1

    Any ideas why this is failing?

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Add the appropriate include for Edge in the source file.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Strange problem with classes in header files
    By samGwilliam in forum C++ Programming
    Replies: 2
    Last Post: 02-29-2008, 04:55 AM
  2. classes and header files
    By Drake in forum C++ Programming
    Replies: 8
    Last Post: 11-30-2006, 07:12 PM
  3. Learning how to use classes and create header files
    By Welshy in forum C++ Programming
    Replies: 10
    Last Post: 04-19-2005, 12:33 PM
  4. Header Files and Classes.
    By Lithorien in forum C++ Programming
    Replies: 10
    Last Post: 08-13-2004, 12:10 PM
  5. Using c++ standards
    By subdene in forum C++ Programming
    Replies: 4
    Last Post: 06-06-2002, 09:15 AM