Базовый класс не определен

Мой код ниже генерирует ошибку

'WorldObject': [Базовый класс не определен (перевод с немецкого)]

Почему это? Вот код, который выдает эту ошибку:

ProjectilObject.h:

#pragma once

#ifndef _PROJECTILOBJECT_H_
#define _PROJECTILOBJECT_H_

#include "GameObjects.h"
class WorldObject;
class ProjectilObject: public WorldObject
{
public:
    ProjectilObject(IGameObject* parent,int projectiltype);

    void deleteyourself();
protected:
virtual void VProcEvent( long hashvalue,    std::stringstream &stream);
    virtual void VInit();
    virtual void VInitfromStream( std::stringstream &stream     );
    virtual void VonUpdate();
    virtual void VonRender();
private:
    vec3 vel;

    float lifetime;
    float lifetimeend;

    vec3 target;

    int m_projectiltype;
};

#endif

Вот файл кода из класса WorldObject:

GameObjects.h:

#pragma once

#ifndef _GAMEONJECTCODE_H_
#define _GAMEONJECTCODE_H_

#include "IGameObject.h"
#include "Sprite.h"
#include "GamePath.h"
#include "HashedString/String.h"
#include "IAttribute.h"
#include "CharacterObjects.h"

...

class WorldObject: public IGameObject, public MRenderAble
{
public:
    WorldObject(IGameObject* parent);
    virtual bool IsDestroyAble();
    virtual bool IsMageAble();
    virtual bool IsRenderAble();
protected:
    virtual void VProcEvent( long hashvalue, std::stringstream &stream);
    virtual void VonUpdate();
    virtual void VonRender();
    virtual void VInit() =0;
    virtual void VInitfromStream( std::stringstream &stream ) =0;
    virtual void VSerialize( std::stringstream &stream );

    vec3 poscam;    
};

...

#endif

В этом файле есть еще какие-то классы, но я не думаю, что они должны иметь значение. Может быть, есть крошечная ошибка, которую я не видел, но я не понимаю, почему эта ошибка возникает. Когда вам нужно больше кода, не стесняйтесь.


person JimRaid    schedule 20.05.2012    source источник
comment
Вы имели в виду MRenderable вместо MRenderAble? Кроме того, у вас есть круговые зависимости между двумя файлами. Вместо этого вам нужна предварительная декларация.   -  person chris    schedule 20.05.2012
comment
@chris Та же ошибка с предварительным объявлением и без него. MRenderable и MRenderAble не имеют отношения к проблеме. Я думаю. MRenderAble — еще один класс, который я создал в файле IAttribute.h.   -  person JimRaid    schedule 20.05.2012
comment
Что ж, вам нужно включить полный класс, чтобы наследовать его, поэтому форвардное объявление здесь бесполезно, но в вашем GameObjects.h форвардного объявления ProjectilObject.h, вероятно, будет достаточно.   -  person chris    schedule 20.05.2012
comment
Вы можете наследовать только от типа complete.   -  person Kerrek SB    schedule 20.05.2012


Ответы (3)


Если у вас есть какой-либо исходный файл, который включает GameObjects.h перед ProjectilObject.h или не включает ProjectilObject.h напрямую, то компилятор сначала найдет объявление ProjectilObject через включение в GameObjects.h, прежде чем узнает, что такое WorldObject. Это потому, что GameObjects.h сначала включает ProjectilObject.h, а затем объявляет WorldObject. В этом случае включение GameObjects.h в ProjectilObject.h не сработает, потому что _GAMEONJECTCODE_H_ уже определено.

Чтобы избежать этого, либо обязательно включите ProjectilObject.h вместо GameObjects.h в исходный файл, либо используйте форвардные объявления .

person gztomas    schedule 20.05.2012
comment
Ссылка на предварительные объявления конкретно указывает, что вы не можете использовать ее для определения базового класса. - person IAmTheAg; 23.11.2014

Трудно ответить на этот вопрос, не глядя на весь код. Даже неуместная скобка может иметь значение. Проверьте свои пространства имен — вы уверены, что WorldObject находится в том же пространстве имен?

Я предлагаю вам использовать сообщение #pragma, поместив его рядом с определением WorldObject и проверив вывод компилятора:

Сообщение #pragma ("Объект мира определен")

Если он не отображается, переместите прагму в родительский файл .h и снова проверьте вывод компилятора. С этим вы можете легко найти ошибку.

person Vladimir Sinenko    schedule 20.05.2012

В моем случае: я удаляю производный класс из файла заголовка базового класса.

Например:

файл 1: #include B.h

-> A()

файл 2:

-> B() : A()

решение: удалить #include B.h из файла1

person rkilic    schedule 15.09.2020