类前向声明​​失败,没有递归包含

Posted

技术标签:

【中文标题】类前向声明​​失败,没有递归包含【英文标题】:Class forward declaration fails, No recursive include 【发布时间】:2013-07-20 05:31:53 【问题描述】:

我正在使用 VS2008 并在 MFC 中为学校项目进行开发。 代码结构由 bouml 4 生成,当我想使用它时出现问题。 我被错误 C2061: syntax error : identifier 'Node' 卡住了几个小时,不知道如何解决它。 这是发生编译错误的地方。

链接.h

#pragma once

#include "model/MapIndicator.h"
#include "model/Highlightable.h"

class Node;
struct COORDINATE_AREA;

class Link : public MapIndicator 
public:
    explicit Link();
    Link(Node * node1, Node * node2); // Error on this line
protected:
    Link(const Link & source);
public:
    virtual ~Link(); 
...

节点.h

#pragma once

#include "model/MapIndicator.h"
#include <vector>
using std::vector;
#include "model/COORDINATE.h"
#include "model/Highlightable.h"

class Site;
struct COORDINATE_AREA;

//Node will be repaint several times in one refresh.
class Node : public MapIndicator 
public:
    explicit Node();

protected:
    Node(const Node & source);

public:
    virtual ~Node();

private:
    Node & operator=(const Node & source);

public:
    //This function will only add other node in its adjacent node list.
    //Note: Duplicate adding will have no effect.
    void addAdjNode(Node * otherNode);

    vector<Node *>::size_type getAdjNodeCount();

    //Remove specified node from its adjacent node list.
    //Return true if succeeds, Return false if that node doesn't exist in list.
    bool removeAdjNode(const Node * adjNode);

    //Add site which use this instance as reference node to referenced site list.
    void addRefSite(Site * refSite);

    vector<Site *>::size_type getRefSiteCount();

    //Remove specified site from its referenced site list.
    //Return true if succeeds, Return false if that site doesn't exist in list.
    bool removeRefSite(const Site * refSite);

    inline COORDINATE getNodeCoordinate() const;

    void setNodeCoordinate(COORDINATE value);

    //Draw itself according to the size and the coordinate of display area and its own coordinate.
    virtual void DrawInRect(const RECT & viewDispRect, const COORDINATE_AREA & mapDispCoordinate, CDC * pDC);

    //Return true if indicator have something to show in the coordinate area specified in parameter, otherwise return false.
    virtual bool VisibleInArea(const COORDINATE_AREA & mapDispCoordinate);

    //Return distance in double between screen position of this indicator and the screen point.
    virtual double DistanceInPixel(const RECT & viewDispRect, const COORDINATE_AREA & mapDispCoordinate, const CPoint & point);

    //Set display state directly.
    virtual void SetDispState(DispState dispState);

    //If hover is true and current state is normal, set state to hover.
    //If hover is false and current state is hover, set state to normal.
    //Otherwise no effect.
    virtual void SetHover(bool hover);

private:
    vector<Node *> adjNodes;

    vector<Site *> referencedSites;

    COORDINATE nodeCoordinate;

;
inline COORDINATE Node::getNodeCoordinate() const 
  return nodeCoordinate;

MapIndicator.h

#pragma once

#include "model/MapObject.h"
#include "model/Drawable.h"
#include "model/Locatable.h"
#include "model/Highlightable.h"

struct COORDINATE_AREA;

//This enum specifies different kinds of indicators available to identify.
enum IndicatorType 
  Road,
  Link,
  Node,
  Site

;
//MapIndicator is a artifact on map given varies kinds of hint to user.
class MapIndicator : public MapObject, public Drawable, public Locatable, public Highlightable 
public:
    explicit MapIndicator(IndicatorType indicatorType);
...

而且 MapObject、Drawable、Locatable 和 Highlightable 的 header 中没有 include 语句,只有 #pragma 一次。

和领先的编译输出:

1>Link.cpp
1>c:\project\model\link.h(12) : error C2061: syntax error : identifier 'Node'
1>c:\project\model\link.h(12) : error C2535: 'Link::Link(void)' : member function already defined or declared
1>        c:\project\model\link.h(11) : see declaration of 'Link::Link'

实际上这个错误在我的项目中无处不在,但为什么呢?我用的是指针,没有递归包含。

【问题讨论】:

上面代码中的类Node声明在哪里? 不要进行前向声明,而是尝试直接包含 Node.h。其实我没有VS,否则我也会在我的系统中尝试。 包含没问题,我试过了。但是为什么前向声明失败了。我不应该在几乎每个标题中都包含大标题。 我不能在相关标题中这样做,否则会发生递归包含。 好的,我发现我在 MapIndicator.h 中定义的枚举与类名有名称冲突。我要感谢我们出色的编译消息...OTL... 【参考方案1】:

好的,我发现我在 MapIndicator.h 中定义的枚举与类名存在名称冲突。 我要感谢我们出色的编译消息...OTL...

【讨论】:

以上是关于类前向声明​​失败,没有递归包含的主要内容,如果未能解决你的问题,请参考以下文章

类前向声明​​ C++

class 类前向声明

Python之函数参数局部全局变量前向引用递归

第21课 可变参数模板_展开参数包

如何在 CORBA IDL 中声明/使用对结构的前向引用?

“递归索引在级别 4 失败”R 代码