Archived

This topic is now archived and is closed to further replies.

Ledneh

Base class undefined? HELP!

Recommended Posts

Okay, building a D3D App. I have two objects: CObject and CBlock (declared/defined in Object.h/cpp and Block.h/cpp, respectively). CBlock, in theory, is supposed to inherit from CObject (which, by the way, has one of those "undefined" functions, I forget what they''re called... Code''s posted below, let me know if you know). However, the code below gives a "''CObject'': Base class undefined" error. Help: Object.h
#pragma once

#include "Direct3D.h"
#include <time.h>

class CObject
{
public:
	virtual void Update();
	virtual void Render()=0;
	CObject();
	~CObject();

// ...and so forth... //
};
 
Block.h
#pragma once

#include "Direct3D.h"
#include "Object.h"

class CBlock : public CObject
{
public:
	CBlock();
	~CBlock();

	void Render();

private:
	int m_blockX; // in relation to playing field
	int m_blockY;
	D3DCOLOR m_color; // make this completely random?
};
 
That''s it. If anyone can help, I''d appreciate it.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
They're pure virtual functions. And base class destructor should be virtual. Otherwise this'll happen:
  
CObject* object = new CBlock();
delete object; //!!!ALERT, CBlock destructor won't be called


But that doesn't solve your problem. It might have something to do with the "#pragma once"s..

[Edit: The [source] tag, however, is not intended for code snippets that fit within the window width and are less than 10 lines long... People find it irritating. ]

[edited by - Oluseyi on October 4, 2002 6:33:08 PM]

Share this post


Link to post
Share on other sites
I didn't include the definitions, simply because it would only cause needless spam. Block.cpp includes Block.h, and Object.cpp includes Object.h.

Also, CObject::Update() isn't pure virtual because it IS defined in Object.cpp--CObject::Render() is the only one meant to be pure virtual.

[edited by - Ledneh on October 2, 2002 4:47:23 PM]

Share this post


Link to post
Share on other sites
Something that''s probably pretty obvious, but the error only occurs when Block.h is included anywhere in my project. Including Object.h doesn''t help (or cause) this error.

Share this post


Link to post
Share on other sites
  • Is there anything in Direct3D.h that might cause the preprocessor to look over CObjects definition (like an #ifdef/#ifndef without a matching #endif)?


  • In which cpp file does the error occur?


  • What complier are you using?



  • [edited by - Solo on October 2, 2002 11:24:41 PM]

    Share this post


    Link to post
    Share on other sites
    Here's the build log--note that this error does NOT occur if Block.h isn't included in the project anywhere but Block.cpp (having Block.cpp include it is just fine, it's just when any other file includes Block.h that I get problems.)


      
    ------ Build started: Project: DXTris, Configuration: Debug Win32 ------

    Compiling...
    Window.cpp
    Generating Code...
    Compiling...
    Object.cpp
    c:\Documents and Settings\Student\Desktop\DXTris\Block.h(9) : error C2504: 'CObject' : base class undefined
    Direct3D.cpp
    DXTest.cpp
    Block.cpp
    Generating Code...

    Build log was saved at "file://c:\Documents and Settings\Student\Desktop\DXTris\Debug\BuildLog.htm"

    DXTris - 1 error(s), 0 warning(s)


    Note, there's no errors in Object.cpp as far as I can see--all it has are the definitions for the functions in CObject, and a #include "Object.h" at the top.

    Oh yeah, and this is in MSVC++ .NET.

    -Ledneh

    [edited by - Ledneh on October 4, 2002 1:55:10 PM]

    [edited by - Ledneh on October 4, 2002 1:59:27 PM]

    [Edit: The [source] tag also scrolls horizontally...]

    [edited by - Oluseyi on October 4, 2002 6:31:57 PM]

    Share this post


    Link to post
    Share on other sites
    quote:
    Original post by Ledneh

    Compiling...
    Object.cpp
    c:\Documents and Settings\Student\Desktop\DXTris\Block.h(9) : error C2504: ''CObject'' : base class undefined


    Ah ha! Why is Object.cpp accessing the Block.h header?

    Post your Object.cpp; the problem seems to be there.


    Don''t listen to me. I''ve had too much coffee.

    Share this post


    Link to post
    Share on other sites
    Okey-dokie, I'll cut and paste...you've been warned, this is an official SPAM ALERT!!!!!

    Object.cpp

      
    #include "Object.h"

    CObject::CObject()
    {
    m_setVel.x = m_setVel.y = 0;
    m_currentVel.x = m_currentVel.y = m_currentPos.x = m_currentPos.y = 0;

    m_lastUpdateTime = GetTickCount() / 1000.0;
    }

    CObject::~CObject()
    {

    }

    void CObject::Update()
    {
    // calculate velocity related to computer speed

    double time = (GetTickCount() / 1000.0) - m_lastUpdateTime;

    m_currentVel.x = m_setVel.x * time;
    m_currentVel.y = m_setVel.y * time;
    m_currentPos.x += m_currentVel.x;
    m_currentPos.y += m_currentVel.y;

    D3DXMATRIX mat;

    D3DXMatrixTranslation(&mat, m_currentPos.x, m_currentPos.y, 0);

    CDirect3D::GetSingleton()->GetDevice()->SetTransform(D3DTS_WORLD, &mat);

    // When did we last do something?

    m_lastUpdateTime = GetTickCount() / 1000.0;
    }

    void CObject::Render()
    {
    CDirect3D::GetSingleton()->GetDevice()->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
    }

    void CObject::SetVel(double x, double y)
    {
    m_setVel.x = x;
    m_setVel.y = y;
    }

    void CObject::SetPos(double x, double y)
    {
    m_currentPos.x = x;
    m_currentPos.y = y;
    }


    Object.h

      
    #pragma once

    #include "Direct3D.h"

    #include <d3d8.h>
    #include <d3dx8.h>

    class CObject
    {
    public:
    virtual void Update();
    virtual void Render();
    CObject();
    virtual ~CObject();

    void SetVel(double x, double y); // velocities set per second

    void SetPos(double x, double y);

    D3DXVECTOR2 GetVel() {return m_setVel;}
    D3DXVECTOR2 GetPos() {return m_currentPos;}

    private:
    D3DXVECTOR2 m_currentPos;
    D3DXVECTOR2 m_currentVel;
    D3DXVECTOR2 m_setVel;

    double m_lastUpdateTime;
    };


    Block.cpp (no special functionality here yet, just making the point about my problem)

    #include "Block.h"

    CBlock::CBlock()
    {
    }

    CBlock::~CBlock()
    {
    }


    Block.h

    #pragma once

    #include "Object.h"

    class CBlock : public CObject
    {
    public:
    CBlock();
    virtual ~CBlock();

    private:
    };


    Again, just to clarify... the problem ONLY comes when another file in my project not listed here tries to include Block.h. If I don't include Block.h (which is not in use yet, thank God) anywhere else in my project, everything works hunky-dory.

    -Ledneh, who really does apologize for the spamminess.

    [Edit: the [source][/source] tags exist to deal with such "spamminess", as they maintain their own scroll positions.]

    [edited by - Oluseyi on October 4, 2002 6:31:01 PM]

    Share this post


    Link to post
    Share on other sites
    The original problem was that CBlock derives from CObject, but doesn't fulfill the obligation that the inheritance implies.
    That is to say, CBlock MUST implement all pure virtual methods in CObject to be instantiatable. You have to provide an implementation for void Render() in CBlock.

    Add:
        
    void Render()
    {
    }

    [Edit (Oluseyi): 3 lines of code, [source] tag?]

    to Block.cpp and everything will be ok...

    All virtual methods must have an implementation somewhere, or you'll get fairly cryptic linker errors.


    Hmmm... Ok, I see your new problem. You forgot to add macro guards to your header files.

    Like so for Object.h:
                    
    #ifndef OBJECT_H_
    #define OBJECT_H_


    // Your class declaration goes here.

    #endif

    Do the same kind of thing in Block.h, and you should be fine.



    edit: Arg, source formatting.

    There are 10 kinds of people in the world: those who get binary, and those who don't...

    [edited by - doomx on October 4, 2002 6:19:47 PM]

    [edited by - Oluseyi on October 4, 2002 6:34:54 PM]

    Share this post


    Link to post
    Share on other sites
    quote:
    mm... Ok, I see your new problem. You forgot to add macro guards to your header files.

    In MSVC++, using #pragma once automatically does this.

    edit {
    quote:
    Block.h(9) : error C2504: 'CObject' : base class undefined

    For future reference, look at the line number. You will notice that line 9 is "void Render();" and you should be able to deduce that there is a problem involving that function.
    }


    [edited by - Neosmyle on October 4, 2002 6:45:49 PM]

    Share this post


    Link to post
    Share on other sites
    I think Sneftel had the answer.

    Object.cpp includes object.h... object.h includes "Direct3D.h" and some DX headers, but somehow you get an error in block.h. This implies that Direct3d.h includes block.h, which requires knowledge of object.h for inheritance purposes. Now, the file "object.h" has already been included, and the #pragma once prevents it being included a second time... but the actual definition in object.h of CObject has not been encountered yet, so CBlock cannot be defined.

    The solution? Remove the circular dependency. Avoid having headers including other headers wherever possible. Or split headers up into logical parts so that you can use the definitions in one part without dragging in all the dependencies that the other one requires.

    [ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost | Asking Questions | Organising code files | My stuff ]

    Share this post


    Link to post
    Share on other sites
    When headers depend on each other, try and restructure your dependencies. If you can''t seem to do this, try adding class forwards to the part outside of the #ifndef/#endif block, so that regardless if the header has been included in the current translation unit, it knows that the class exists. I.e.


      
    class SomeClass;

    #ifndef SOMECLASS_H
    #define SOMECLASS_H

    class SomeClass
    {
    ...
    };

    #endif

    Share this post


    Link to post
    Share on other sites
    make sure "direct3d.h" doesnt include block.h nor object.h. Move your #include "direct3d.h" into object.cpp anyway if you dont need it in the header.

    edit - i should probably refresh the page if i leave it on overnight

    [edited by - sark on October 5, 2002 2:26:53 AM]

    Share this post


    Link to post
    Share on other sites
    Damn me and my cleverly hidden circular dependencies. Damn me.

    Thanks folks, I don''t know what I''d do without you. You were right; because of the way my #includes were organized, I ended up having block.h re-include itself before it included it''s own base. Fixed.

    -Ledneh -- "Where''s me drink?!"

    Share this post


    Link to post
    Share on other sites