Thread: vector trouble

  1. #1
    Registered User
    Join Date
    Oct 2006
    Location
    UK/Norway
    Posts
    485

    vector trouble

    Hallo,

    I am having a problem with creating a vector that contains Triangles, which is a class I have made myself.

    Code:
    #ifndef INPUT_H
    #define INPUT_H
    
    
    #include "CommonMath.h"    // Math stuff 
    #include "Primitives.h"    // Needed for Triangle 
    #include <vector>          // For easy use of dynamic arrays
    
    // Create an array of triangles after reading the vertex 
    // cordinates from a file
    std::vector<Triangle> loadFromFile(std::string FileName);
    
    #endif
    As you see the whole thing is really simple, but still it does not work.
    The error I get is : `Triangle' was not declared in this scope

    Thanks

  2. #2
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Well, was it? Perhaps it's in a namespace.

    What's in Primitives.h?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  3. #3
    Registered User
    Join Date
    Oct 2006
    Location
    UK/Norway
    Posts
    485
    What's in Primitives.h?
    Code:
    class Primitive
    {
          public:
                 Primitive(std::string n = "DefaultName");
                 //~Primitive();
                 
                 void setName(std::string n);   
                 virtual std::string getName();
                 
                 void setMaterial(Material m);
                 virtual Material* getMaterial();
                 
                 virtual Vector3D getPos() = 0;
                 
                 virtual result intersectionTest(Ray r) = 0;
                 
          private:
                  //type
                  std::string name;
                  Material material;
    };
    
    // The subclass for a sphere
    class Sphere : public Primitive
    {
          public:
                 Sphere(Vector3D pos, float r);
                 float getRadius();
                 float getRadiusSqr();
                 
                 void setPos(Vector3D pos);
                 Vector3D getPos();
                 
                 result intersectionTest(Ray r); 
          private:
                  float radius;
                  Vector3D position;
    };
    
    
    class Triangle : public Primitive
    {
          public:
                 Triangle(Vector3D _v1, Vector3D _v2, Vector3D _v3);
                 result intersectionTest(Ray r);
                 
                 Vector3D getPos();
          private:
                  // The three vertexes
                  Vector3D v1;
                  Vector3D v2; 
                  Vector3D v3;
    };
    
    // mesh class
    class Mesh : public Primitive
    {
          public:
                 Mesh(std::string fName);
                 
                 result intersectionTest(Ray r);
                 Vector3D getPos();
                 // loadFromFile();
                 // bounding box
                 // getNormalX(int triangle)
                 
                 
          private:
                  // triangleList class Triangle?
                  // No of triangles
    };
    thats what I have in the file and as you see its here Triangle is declared. What do you mean about the namespace thing?

    Thanks

  4. #4
    The larch
    Join Date
    May 2006
    Posts
    3,573
    May-be you should also include string?
    Are you sure there are no circular dependencies?

  5. #5
    Registered User
    Join Date
    Oct 2006
    Location
    UK/Norway
    Posts
    485
    May-be you should also include string?
    Yes, you are right, but it works as it is already included in CommonMath and Primitives.h

    Are you sure there are no circular dependencies?
    Sorry to ask, but that is that?

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Does your .h file have an #ifndef guard? Did you possibly screw up and use #ifdef instead of #ifndef?

  7. #7
    Registered User
    Join Date
    Oct 2006
    Location
    UK/Norway
    Posts
    485
    Does your .h file have an #ifndef guard? Did you possibly screw up and use #ifdef instead of #ifndef?
    No, and also the classes from Primitive.h is used in other files without trouble.

    Can it have something to do with Triangle being a subclass of Primitive?

  8. #8
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by h3ro View Post
    No, and also the classes from Primitive.h is used in other files without trouble.

    Can it have something to do with Triangle being a subclass of Primitive?
    What .cpp file is this loadFromFile() function declared in? Are all the proper headers being included there?

    If you are willing to post an archive containing everything, I'll have a look.

    EDIT: Sometimes this message arises because of a missing semicolon at the end of a struct or class declaration.
    Last edited by brewbuck; 05-02-2007 at 02:55 PM.

  9. #9
    Registered User
    Join Date
    Oct 2006
    Location
    UK/Norway
    Posts
    485
    If you are willing to post an archive containing everything, I'll have a look.
    Thats very nice of you
    http://rapidshare.com/files/29263271/Raytracer.rar.html

  10. #10
    Registered User
    Join Date
    Sep 2001
    Posts
    752
    Primitives.h includes input.h
    input.h includes Primitives.h

    The error is happening because input.h is being included into primitives.h.
    Callou collei we'll code the way
    Of prime numbers and pings!

  11. #11
    Registered User
    Join Date
    Oct 2006
    Location
    UK/Norway
    Posts
    485
    But I need them to know about each other. Is there a workaround for this?

  12. #12
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Why do you need Primitives.h to know about Input.h? (I didn't look in your archive.)

    In general, use a forward declaration inside a header file rather than an include when you can.

  13. #13
    Registered User
    Join Date
    Sep 2001
    Posts
    752
    Well, if they really need to know about each other, then there's a basic design problem, but I don't think that's the case...

    • Does primitives.h really need input.h; or does only primitives.cpp need to know about input.h? You should shoot for a few nested-headers as neccesary.
    • If I understand correctly... the problem is in class Mesh. It's perfectly fine to put Mesh off in a class on it's own, removing primitives.h's dependency on input.h
    Callou collei we'll code the way
    Of prime numbers and pings!

  14. #14
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    My general rule is that a header should only include another header if the former header absolutely REQUIRES the full definition of a type provided by the other header. If the interface specified by the header file requires only the NAME of a type, but doesn't need to know its definition, then the header can just forward-declare the type itself. This can end up saving you a LOT of compile time, because headers don't have to get parsed over and over again in each module which only references a type incidentally (e.g. via a pointer, without dereferencing).

    One approach is to make pairs of header files. One header forward-declares the types, the other defines them.

    Code:
    /* File: primitive_forward.h */
    
    class Primitive;
    Code:
    /* File: primitive.h */
    
    #include "primitive_forward.h"
    
    class Primitive
    {
        /* Class is defined here */
    };
    Then, you can choose to include only primitive_forward.h in modules which only reference pointers to Primitive. For modules that actually need the definition of Primitive, they include primitive.h.

    It looks unnecessary to include primitive_forward.h from primitive.h, and strictly, it IS unnecessary, but it serves a purpose. If you alter the nature of Primitive, say, by making it a typedef of another type, and you forget to change it in both files, the compiler will give an error, instead of silently compiling broken code.

    I know that might not make much sense to you yet, but eventually it will.
    Last edited by laserlight; 05-03-2007 at 12:33 PM. Reason: Wrong thread: moved by request.

  15. #15
    Registered User
    Join Date
    Oct 2006
    Location
    UK/Norway
    Posts
    485
    Thanks for the help everyone, it works now (Did it the easy way, by including primitives.h in input.cpp)

    brewbuck: That made perfectly sense, and thanks for the tip. Ill do that when I redesign my simple raytracer. I have already restarted it ones, but as I learn more and more I see errors in the base of the programs which need to be changed, so back to the start.

    Just a question to the ones who looked at the source code, is my programing hard to read, or did it go ok?

    Edit: Does anyone here written a raytracer before? I have a few questions that I would ask, but not sure if this forum is appropriate for that?

    Thanks once again to the members of this forum for outstanding help.

Popular pages Recent additions subscribe to a feed