C ++ for arduino - 错误:class没有命名类型

时间:2018-05-06 18:19:54

标签: c++ arduino

我是java的专家,但不是C和C ++的专家。我正在尝试为我的Arduino项目开发C ++ API。 4个单独的文件中有两个类(标题.h和.cc文件)。 CDScreen 类是 CDFrame 对象的容器。

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

类CDFrame的标头中的这个添加导致类CDScreen的标题中的汇编错误(' CDFrame'没有命名类型CDScreen.h)。 具体来说,我注意到问题是由CDFrame的.h文件顶部的CDScreen.h文件声明引起的。 编译似乎在那时停止了。

这里出了什么问题?怎么可能创建一个属性为B的A类,而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;   
}

2 个答案:

答案 0 :(得分:2)

多年前,当我在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;   
}

答案 1 :(得分:2)

问题是C ++在使用之前是声明的,因此必须先声明任何类型才能使用它。 (其中&#34;之前&#34;表示&#34;在源文本&#34;上面。)对于具有循环依赖关系的类型,这意味着类型需要声明才能定义。这是通过前向声明来完成的,它只是简单地引入了名称,而没有定义类型。在这种情况下,这样的声明将是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;   
}