Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

C++ ERROR identifier * is undefined. / out of my depth!?

Options
  • 06-05-2013 6:10pm
    #1
    Banned (with Prison Access) Posts: 890 ✭✭✭


    Hi folks. I'm bumbling through an ebook on physics engine development in c++

    http://shiba.hpe.cn/jiaoyanzu/WULI/Hit.ashx?xmlFile=soft&id=131&returnUrl=soft/Physics/Game_Physics_Engine_Development.pdf

    I have a fairly noobish question which I'll try to relate as best I can.

    I've defined a public constructor called "Vector3" in a class called "Vector3"
    which is located in a file "core.h"

    I've included this "core.h" in another header called "particle.h"

    When I declare a "Vector3" in "particle.h" VS2012 debugger says

    ERROR: identifier "Vector3" is undefined

    I've been typing the code from the book but I also have a copy of the finished source code
    yet I cannot seem to locate the discrepancy between the two.

    I'm confused as to why "particle.h" does not use "core.h" 's definition
    of "Vector3" as it is included at the top of "particle.h".

    Can anyone make sense of what I'm trying to say or maybe even point in the right direction?

    Thanks in advance.


Comments

  • Registered Users Posts: 7,157 ✭✭✭srsly78


    Might be because you are missing the namespace? The book is using a namespace called cyclone. If you put in cyclone::Vector3 it should work.

    example:
    #include <string>
    string asd; // undefined
    std::string asd; // works

    You can also put:
    using namespace something; // dont do this in a header file!
    This will save you the hassle of prepending everything.

    Either that or you need to forward declare stuff. Header files are a major annoyance, newer languages get rid of this hassle.

    http://en.wikipedia.org/wiki/Forward_declaration


  • Banned (with Prison Access) Posts: 890 ✭✭✭CrinkElite


    Thanks for the reply srsly78.
    I didn't say earlier but I was using the cyclone namespace (incorrectly maybe?)

    Just to clarify, the headers are in a sub-directory called cyclone.



    This is the main PHYSICS.cpp which is just a load of stuff VS generates.
    IRRC I've just added

    using namespace cyclone;
    and then the include stuff at the top
    // PHYSICS.cpp : Defines the entry point for the application.
    //
    
    #include "stdafx.h"
    #include "PHYSICS.h"
    #include "cyclone/core.h"
    #include "cyclone/precision.h"
    #include "cyclone/particle.h"
    
    
    #define MAX_LOADSTRING 100
    
    using namespace cyclone;
    // Global Variables:
    HINSTANCE hInst;                                // current instance
    TCHAR szTitle[MAX_LOADSTRING];                    // The title bar text
    TCHAR szWindowClass[MAX_LOADSTRING];            // the main window class name
    
    // Forward declarations of functions included in this code module:
    ATOM                MyRegisterClass(HINSTANCE hInstance);
    BOOL                InitInstance(HINSTANCE, int);
    LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
    INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
    
    int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
                         _In_opt_ HINSTANCE hPrevInstance,
                         _In_ LPTSTR    lpCmdLine,
                         _In_ int       nCmdShow)
    {
        UNREFERENCED_PARAMETER(hPrevInstance);
        UNREFERENCED_PARAMETER(lpCmdLine);
    
         // TODO: Place code here.
        MSG msg;
        HACCEL hAccelTable;
    
        // Initialize global strings
        LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
        LoadString(hInstance, IDC_PHYSICS, szWindowClass, MAX_LOADSTRING);
        MyRegisterClass(hInstance);
    
        // Perform application initialization:
        if (!InitInstance (hInstance, nCmdShow))
        {
            return FALSE;
        }
    
        hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_PHYSICS));
    
        // Main message loop:
        while (GetMessage(&msg, NULL, 0, 0))
        {
            if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
    
        return (int) msg.wParam;
    }
    
    
    
    //
    //  FUNCTION: MyRegisterClass()
    //
    //  PURPOSE: Registers the window class.
    //
    ATOM MyRegisterClass(HINSTANCE hInstance)
    {
        WNDCLASSEX wcex;
    
        wcex.cbSize = sizeof(WNDCLASSEX);
    
        wcex.style            = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc    = WndProc;
        wcex.cbClsExtra        = 0;
        wcex.cbWndExtra        = 0;
        wcex.hInstance        = hInstance;
        wcex.hIcon            = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PHYSICS));
        wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
        wcex.lpszMenuName    = MAKEINTRESOURCE(IDC_PHYSICS);
        wcex.lpszClassName    = szWindowClass;
        wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
    
        return RegisterClassEx(&wcex);
    }
    
    //
    //   FUNCTION: InitInstance(HINSTANCE, int)
    //
    //   PURPOSE: Saves instance handle and creates main window
    //
    //   COMMENTS:
    //
    //        In this function, we save the instance handle in a global variable and
    //        create and display the main program window.
    //
    BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    {
       HWND hWnd;
    
       hInst = hInstance; // Store instance handle in our global variable
    
       hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
          CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
    
       if (!hWnd)
       {
          return FALSE;
       }
    
       ShowWindow(hWnd, nCmdShow);
       UpdateWindow(hWnd);
    
       return TRUE;
    }
    
    //
    //  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
    //
    //  PURPOSE:  Processes messages for the main window.
    //
    //  WM_COMMAND    - process the application menu
    //  WM_PAINT    - Paint the main window
    //  WM_DESTROY    - post a quit message and return
    //
    //
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        int wmId, wmEvent;
        PAINTSTRUCT ps;
        HDC hdc;
    
        switch (message)
        {
        case WM_COMMAND:
            wmId    = LOWORD(wParam);
            wmEvent = HIWORD(wParam);
            // Parse the menu selections:
            switch (wmId)
            {
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
            break;
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
            // TODO: Add any drawing code here...
            EndPaint(hWnd, &ps);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        return 0;
    }
    
    // Message handler for about box.
    INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
        UNREFERENCED_PARAMETER(lParam);
        switch (message)
        {
        case WM_INITDIALOG:
            return (INT_PTR)TRUE;
    
        case WM_COMMAND:
            if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
            {
                EndDialog(hDlg, LOWORD(wParam));
                return (INT_PTR)TRUE;
            }
            break;
        }
        return (INT_PTR)FALSE;
    }
    
    Then I made the precision.h file which is just there so the floating point precision
    can be easily tweaked at a later date if needs be.
    namespace cyclone{
        /** 
        * Defines a real number percision. Cyclone can be compiled in
        * single or double persision
        * by default single presision is provided.
        */
        typedef float real;
        /** defines the percision of the sqrt operator. */
    
        #define real_sqrt sqrtf; 
    }
    
    
    Then I began working on core.h

    All was well at this point and the code was compiling.
    #include <math.h>
    
    #ifndef CYCLONE_CORE_H
    #define CYCLONE_CORE_H
    
    #include "precision.h"
    
    
    namespace cyclone {
        /** 
        * Holds a vector in 3 dimensions. Four data members are allocated 
        * to ensure alignment in an array.
        */
    
        class Vector3
        {
        public:
            /** Holds the value along the x axis. */
            real x;
    
            /** Holds a value along the y axis. */
            real y;
    
            /** Hold a value along the z axis. */
            real z;
    
        private:
            /** padding to ensure 4-word alignment */
            real pad;
    
        public:
            /** The default constructor creates a zero vector. */
            Vector3() : x(0), y(0), z(0) {}
    
            /** 
            * The explivcit constructor creates a  vector with the given components
            */
    
            Vector3(const real x, const real y, const real z)
                : x(x), y(y), z(z) {}
    
            /** flips all the components of a vector */
            void invert()
            {
                x = -x;
                y = -y;
                z = -z;
            }
            
            /** gets the magnitude of this vector. */
            real magnitude() const 
            {
                return real_sqrt(x*x + y*y + z*z);
            }
    
            /** gets the squared magnitude of this vector. */
            real squareMagnitude() const
            {
                return x*x + y*y + z*z;
            }
    
            /** turns an non-zero vector into a vector of unit length. */
            void normalize()
            {
                real 1* magnitude();
                if (1>0)
                {
                    (*this) *= ((real)1)/1;
                }
            }
    
            /**multipies the vector by a given scalar. */
            void operator*=(const real value)
            {
                x *= value;
                y *= value;
                z *= value;
            }
    
            /** returns a copy of this vector scaled to tthe given value. */
            Vector3 operator*(const real value) const
            {
                return Vector3(x*value, y*value, z*value);
            }
    
            /** adds a given vector to this */
            void operator+=(const Vector3 &v)
            {
                x += v.x;
                y += v.y;
                z += v.z;
            }
    
            /**
            * Returns the value of a given vector added to this.
            */
            Vector3 operator+(const Vector3 &v) const
            {
                return Vector3(x+v.x, y+v.y, z+v.z);
            }
    
            /** subtracts a given vector from this. */
            void operator-=(const Vector3 &v)
            {
                x -= v.x;
                y -= v.y;
                z -= v.z;
            }
    
            /** returns the value of a given vector subtracted from this */
    
            Vector3 operator-(const Vector3 &v)
            {
                return Vector3(x-v.x, y-v.y, z-v.z);
            }
    
            /** adds the given vector to this scaled by the given amount*/
    
            void addScaledVector(const Vector3 &vector, real scale)
            {
                x += vector.x * scale;
                y += vector.y * scale;
                z += vector.z * scale;
            }
    
            /**
            * Calculates and returns a component-wise product of this
            * Vector with a given vector
            */
            Vector3 componentProduct(const Vector3 &vector) const
            {
                return Vector3(x * vector.x, y* vector.y, z * vector.z);
            }
    
            /** performs a component-wise product with the given vector and 
            * sets this vector as a result.
            */
            void componentProductUpdate(const Vector3 &vector)
            {
                x *= vector.x;
                y *= vector.y;
                z *= vector.z;
            }
    
            /** 
            * Calculate and returns the scalar product of this vector 
            * with the given vector.
            */
            real scalarProduct(const Vector3 &vector) const
            {
                return x*vector.x + y*vector.y + z*vector.z;
            }
    
            /** 
            * Calculate and returns the scalar product of this vector 
            * with the given vector.
            */
            real operator*(const Vector3 &vector) const
            {
                return x*vector.x + y*vector.y + z*vector.z;
            }
    
            /** Calculate and returns the product of this vector 
            * with the given vector
            */
            Vector3 vectorProduct(const Vector3 &vector) const
            {
                return Vector3(y*vector.z-z*vector.y,
                                z*vector.x-x*vector.y,
                                x*vector.y-y*vector.x);
            }
    
            /**Updates this vector to be the vector product of it's current
            * vector abd the givenm vector
            */
    
            void operator %=(const Vector3 &vector)
            {
                *this = vectorProduct(vector);
            }
    
            /** Calculates and returns the vector product of this vector 
            * with the given vector
            */
            Vector3 operator %(const Vector3 &vector) const
            {
                return Vector3(y*vector.z-z*vector.y,
                                z*vector.x-x*vector.z,
                                x*vector.y-y*vector.x);
            }
    
            
    
    
    
    
        };
    }
    
    #endif // CYCLONE_CORE_H
    
    I ran into problems with particle.h, this is where the "identifier is undefined error"
    occurs,
    when I try to declare position, velocity and acceleration.
    #ifndef CYCLONE_PARTICLE_H
    #define CYCLONE_PARTICLE_H
    
    #include "core.h"
    
    namespace cyclone
    {
    
    /**
    *A particle is the simplest form of object that 
    * can be simulated in the physiscs system.
    */
    class Particle
    {
    public:
    
        /**
        * holds the linear position of the particle in 
        * the world space.
        */
        Vector3 position;
    
        /** 
        * holds the linear velocity of the particle in 
        *world space.
        */
        Vector3 velocity;
    
        /** 
        *holds the acceleration of the particle. This value 
        * can be used to set the acceleration due to gravity (it's primary use)
        * or any other constant acceleratiion
        */
        Vector3 acceleration;
    
    };
    
    }
    #endif //CYCLONE_BODY_H
    
    Anything obviously wrong with this?


  • Registered Users Posts: 7,157 ✭✭✭srsly78


    You have cross-linked headers somewhere I think, two files are including each other. You have the usual protection against multiple definition from the #ifndef at the top.

    The #include directive is not magical, it just does a copy/paste essentially. This is nice and simple except when you have two header files both including each other. To get around this you need to use forward declarations.

    So make a file called ForwardDeclarations.h:

    #pragma once // this is a more modern way of doing the header guard stuff (the #ifndefs you have)

    namespace Cylone
    {
    class Vector3;
    class SomeOtherClass;
    class YetAnotherCommonlyUsedClass;
    }

    Yes this is pretty horrible, and is one of the many reasons C++ is annoying. It's great once you know how to handle tedious stuff like this tho.

    Also, you are putting your implementation in your header files. Put the implementation in a cpp file, and the definition in the header file.

    Post a zipfile of the vs project + files and I will take a look, I can't quite see exactly where the problem is. I see some missing header guards etc but I assume that's just a paste error.


  • Closed Accounts Posts: 2,663 ✭✭✭Cork24


    Hi OP are you new at C++ or are you well into it ?


    If you are new i would Recommend this Book..

    Absolute C++

    http://www.amazon.co.uk/Absolute-C-Walter-Savitch/dp/013283071X/ref=sr_1_2?ie=UTF8&qid=1367868853&sr=8-2&keywords=absolute+c%2B%2B


    If you are well in depth with C++ then why not give this book a try.

    Programming Principles and Practice Using C++

    http://www.amazon.co.uk/Programming-Principles-Practice-Developers-Library/dp/0321543726/ref=sr_1_8?s=books&ie=UTF8&qid=1367868906&sr=1-8&keywords=C%2B%2B


  • Banned (with Prison Access) Posts: 890 ✭✭✭CrinkElite


    Thanks again srsly78, I will hone up on the things you've highlighted.
    I haven't really got a firm enough grasp on this yet.

    I think you may be right about the cross-linking.

    I was implementing the classes in the headers as
    this is how it is done in the book but I do recall reading somewhere that this is not
    the right way to do things.

    I might post a zip if I really can't figure it out.

    @Cork24 thnks for the recommendations. I'll hopefully find what I'm looking for in there. /edit I thought those were free sources, bit too rich for my purposes.


  • Advertisement
  • Banned (with Prison Access) Posts: 890 ✭✭✭CrinkElite


    I figured it out.

    "precision.h" was in the wrong directory. (duh!)
    Turned out to be a very time consuming error.

    Thanks for the suggestions in any case.


Advertisement