【问题标题】: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

标签: c++ class oop inheritance factory


【解决方案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。

【讨论】:

  • 谢谢,这很有意义:)
猜你喜欢
  • 1970-01-01
  • 2021-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多