基类未定义,但包含其标头
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。
【讨论】:
谢谢,这很有意义:)以上是关于基类未定义,但包含其标头的主要内容,如果未能解决你的问题,请参考以下文章
CArray<TYPE,ARG_TYPE>' : 基类未定义