基类未定义,但包含其标头

Posted

技术标签:

【中文标题】基类未定义,但包含其标头【英文标题】:Base class undefined, but its header is included 【发布时间】:2020-05-14 16:16:51 【问题描述】:

我遇到了一些问题,即函数没有返回正确的类型,因为没有定义一个类。我正在使用工厂模式。

我收到的两条错误消息是:

'return': 无法从 'DLA *' 转换为 'Layer *'

和:

'Layer':基类未定义(编译源文件src\Layer.cpp)

对于包含Layer.h 的每个文件都会重复同样的错误消息。

这是我继承自 Layer 的类的样子 (DLA.h):

#pragma once

#ifndef _DLA
#define _DLA

#include "ofMain.h" 
#include "ofxGui.h"
#include "Layer.h"

class DLA: public Layer

public:
    DLA();
    void setup();
    void update();
    void draw();

private:
;

#endif

这是我的Layer 类标题(Layer.h):

#pragma once

#ifndef _LAYER
#define _LAYER

#include "ofMain.h" 
#include "ofxGui.h"
#include "DLA.h"

enum SceneType

    Scene_None,
    Scene_Default,
    Scene_DLA,
;

class Layer


public:

    void setup();
    void update();
    void draw();
    static Layer *CreateSimulation(SceneType Type);


private:
;

#endif

失败的函数是这个,位于Layer.cpp:

Layer *Layer::CreateSimulation(SceneType Type)

    switch (Type)
    
    case Scene_None:
    default:
        return nullptr;
    case Scene_DLA:
        return new DLA();
    

我已经尝试了在 Stack Overflow 上找到的与我有类似问题的所有内容,但我看到有些人建议使用非常微妙的代码缩进来解决这个问题,所以我真的很想知道问题出在哪里。

【问题讨论】:

由于编译错误消息的字符串很长,通常不值得您花时间解决除第一个错误之外的任何错误。以下许多错误是由第一个错误引起的,一旦解决,就会消失(或改变)。基于此 - 您的编译错误链中的第一个错误是什么,正如您的编译器输出它(逐字)? 你应该从Layer.h中删除#include "DLA.h" “Layer.cpp”中是否包含“Layer.h”? 可能不会咬你,但当它滥用下划线时会产生非常奇怪的,几乎难以理解的结果。请阅读What are the rules about using an underscore in a C++ identifier? 了解详情。 我需要Layer.h 中的#include "DLA.h",因为我在帖子末尾提到的Layer *Layer::CreateSimulation(SceneType Type) 函数需要创建一个DLA 对象。我在原始帖子中添加了带有错误消息的图像,是的,我确实在 Layer.cpp 中包含了 Layer.h 【参考方案1】:

就目前而言,您的头文件会导致循环依赖,即使#pragma once(和其他)保护阻止任何实际的“无限递归”。让我们从编译器的角度来看一下在编译Layer.cpp 文件(或任何其他包含#include "Layer.h" 的“.cpp”源)时的代码序列。

编译器遇到#include "Layer.h" (它第一次这样做 - 守卫不会被“触发”),所以它用指示的标题的内容适当地替换了该行。在该内容中,它遇到了#include "DLA.h"(我们可以忽略此讨论中包含的其他标题,假设它们与手头的问题无关)。因此,它会适当地将 that 行替换为 DLA.h 标头的内容,此时它会遇到这个:

#include "Layer.h"

class DLA: public Layer

现在,在这里,当它用标题内容替换#include "Layer.h" 时,该内容将是“空的”(因为有保护,因为它已经包含了该标题一次)。因此,当遇到public Layer 代码时,这是一个错误,因为该类还没有被定义,甚至没有被声明为一个类。

所以,如果您真的坚持Layer.h 中包含#include "DLA.h" 行,那么它必须放在定义之后Layer 类的。

但是,更好的方法是从Layer.h 中删除#include "DLA.h",并仅将其放在实际需要它的 (.cpp) 文件中(如Layer.cpp)。这会很好用:

// Layer.cpp
#include "Layer.h"
#include "DLA.h"   // At this point, references to the Layer class in DLA.h will be fine!

//...

Layer *Layer::CreateSimulation(SceneType Type)

    switch (Type)
    
    case Scene_None:
    default:
        return nullptr;
    case Scene_DLA:
        return new DLA();
    

如有任何进一步的澄清和/或解释,请随时致电 k。

【讨论】:

谢谢,这很有意义:)

以上是关于基类未定义,但包含其标头的主要内容,如果未能解决你的问题,请参考以下文章

错误 C2504:'BASECLASS':基类未定义

CArray<TYPE,ARG_TYPE>' : 基类未定义

Qt - moc 导致 C2504:基类未定义

Swift 类未添加到 Obj-C 项目中 swift 的自动生成标题中

基类未捕获 C++ 异常

基类未捕获 C++ 派生类异常