错误C++:类不命名类型

C++ for error: class does not name a type

本文关键字:类型 C++ 错误      更新时间:2023-10-16

我是Java专家,但不是C和C++方面的专家。我正在尝试为我的Arduino项目开发一个C++的api。 在 4 个单独的文件(标头 .h 和 .cc 文件)中有两个类。类 CDScreenCDFrame对象的容器。

我现在要做的是跟踪 CDFrame 条目的父容器。换句话说,CDFrame 对象需要知道其容器(父级)。 为此,我在 CDFrame 类中添加了一个名为 CDScreen 类型的"parent"的属性。

在类 CDFrame 的标头中添加此内容会导致类 CDScreen 的标头出现编译错误("CDFrame"未命名类型 CDScreen.h)。 具体来说,我注意到问题是由CDFrame的.h文件顶部的CDScreen.h文件的声明引起的。 编译似乎在这一点上停止。

这里出了什么问题?如何创建属性为 B 的类 A,而该类又具有 A 的属性? 这是一个问题还是我的开发方式完全采用类似Java的方式?

CDFrame.h 文件:

#include "CDScreen.h" //<- this cause the problem
#include <stdint.h>
class CDFrame {
public:
CDFrame(uint8_t capacity);
virtual ~CDFrame();
private:
uint8_t capacity = 0;
CDScreen* parent = nullptr; //<- Parent property of CDScreen class
}

和 CDScreen.h 文件:

#include "CDFrame.h"
#include <stdint.h>
class CDScreen {
public:
CDScreen(uint8_t capacity);
virtual ~CDScreen();
void addFrame(CDFrame* frame); // Sets the frame's parent (this CDScreen) when a new frame is added 
private:
uint8_t capacity = 0;
uint8_t size = 0;
CDFrame** frames;   
}

几年前,当我在做一个C++项目时,我也遇到了这种情况。定义类解决了这个问题。

你可以在这里看到我的示例文件:

https://github.com/tkduman/project-x/blob/master/monster.h

https://github.com/tkduman/project-x/blob/master/player.h

他们彼此class monster;class player;,否则行不通。

尝试将文件更新为:

CDFrame.h 文件:

class CDScreen; // add this
#include "CDScreen.h"
#include <stdint.h>
class CDFrame {
public:
CDFrame(uint8_t capacity);
virtual ~CDFrame();
private:
uint8_t capacity = 0;
CDScreen* parent = nullptr; //<- Parent property of CDScreen class
}

CDScreen.h 文件:

class CDFrame; // add this
#include "CDFrame.h"
#include <stdint.h>
class CDScreen {
public:
CDScreen(uint8_t capacity);
virtual ~CDScreen();
void addFrame(CDFrame* frame); // Sets the frame's parent (this CDScreen) when a new frame is added 
private:
uint8_t capacity = 0;
uint8_t size = 0;
CDFrame** frames;   
}

问题是C++在使用之前是声明的,因此任何类型都必须声明才能使用。(其中"之前"是指"源文本中的上方"。对于具有循环依赖关系的类型,这意味着需要先声明这些类型,然后才能定义它们。这是通过前向声明完成的,它只是引入名称,而不定义类型。在这种情况下,这样的声明将是class CDScreen;的。

(请注意,在前向声明之后,可以使用指向类型的指针,但不能使用该类型的实际对象,因为它尚未定义。

与 Java 相反,C++ 不需要您将每个类放在单独的文件中。事实上,通常最好将一组属于/一起操作的类放在一个头文件中。

特别是在像您这样具有循环依赖的情况下,将每个类放在单独的头文件/编译单元中可能会变得非常脆弱。例如,用户包含头文件的顺序可能很重要,导致看似随机的编译错误。

在您的情况下,我认为最好的选择是将类放在同一个文件中,并在顶部添加前向声明。

#include <stdint.h>
class CDScreen;  // forward declarations
class CDFrame;   // (this one is not strictly necessary but put in for symmetry/consistency)
class CDFrame {
public:
CDFrame(uint8_t capacity);
virtual ~CDFrame();
private:
uint8_t capacity = 0;
CDScreen* parent = nullptr; //<- Parent property of CDScreen class
}
class CDScreen {
public:
CDScreen(uint8_t capacity);
virtual ~CDScreen();
void addFrame(CDFrame* frame); // Sets the frame's parent (this CDScreen) when a new frame is added 
private:
uint8_t capacity = 0;
uint8_t size = 0;
CDFrame** frames;   
}