C++ - 嵌套包含 - 避免“包含嵌套太深的错误”

发布于 2024-11-07 17:58:30 字数 954 浏览 0 评论 0原文

如果我想在 C++ 代码中具有以下连接,那么声明头文件的最佳方法是什么,这样我就不会出现“包含嵌套太深的错误”

在我的边缘类上,我有一些需要返回 Node 对象的函数。对于 Edge 类也是如此,我有需要返回 Node 对象的函数。然而编译器不允许我有这个嵌套循环的东西。

Node.h

#ifndef _NODE_h__
#define __NODE_h__

#include "Edge.h" 
public:
    Node();
    ~Node();
    void setName(string);
    string getName();
    void addEdge(Edge*);
    vector<Edge* > getEdges() { return _edges; };
};
#endif

Edge.h

#ifndef _EDGE_h__
#define __EDGE_h__

#include "Node.h"
class Edge 
{
public:

    Edge();
    Edge(bool);
    ~Edge();
    bool hasBeenSeen() { return _seen; };
    void reset() { _seen = false; };  // resets seen param to false
    Node* getSource() { return _source; };
    Node* getTarget() { return _target; };
    void setSource(Node* source) { _source = source; };
    void setTarget(Node* target) { _target = target; };
};
#endif

What is the best way of declaring my header files if I want to have the following connections in my C++ code, just so that I don't get the 'include nested too deeply error'?

On my edge class, I have some functions that need to return a Node object. Same for the Edge class, I have functions that need to return a Node object. However the compiler disallow me to have this nested loop thing.

Node.h

#ifndef _NODE_h__
#define __NODE_h__

#include "Edge.h" 
public:
    Node();
    ~Node();
    void setName(string);
    string getName();
    void addEdge(Edge*);
    vector<Edge* > getEdges() { return _edges; };
};
#endif

Edge.h

#ifndef _EDGE_h__
#define __EDGE_h__

#include "Node.h"
class Edge 
{
public:

    Edge();
    Edge(bool);
    ~Edge();
    bool hasBeenSeen() { return _seen; };
    void reset() { _seen = false; };  // resets seen param to false
    Node* getSource() { return _source; };
    Node* getTarget() { return _target; };
    void setSource(Node* source) { _source = source; };
    void setTarget(Node* target) { _target = target; };
};
#endif

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

‖放下 2024-11-14 17:58:30

正如其他人所建议的,使用标头防护装置。但也尝试向前声明有问题的类。您可能还必须在至少一个类中使用指针(而不是值),但如果没有看到代码,我们无法判断。

因此,edge.h 应该类似于:

#ifndef EDGE_H
#define EDGE_H

class Node;    // forward declaration

Node functionB();

#endif

请注意,您必须在单独的 C++ 文件中定义函数,然后 #includes“node.h”。

如果这一切看起来非常复杂,那么您应该尝试简化您的设计。节点和边可能没有必要相互了解——单向依赖就足够了。

最后,包含双下划线的名称在 C++ 中是保留的 — 不允许您在自己的代码中创建此类名称。

As others have suggested, use header guards. But also try forward declaring the classes in question. You may also have to work with pointers (rather than values) in at least one of your classes, but without seeing the code, we can't tell.

So edge.h should like something like:

#ifndef EDGE_H
#define EDGE_H

class Node;    // forward declaration

Node functionB();

#endif

Note that you will have to define your function in a separate C++ file which then #includes "node.h".

If all this seems very complicated, then you should try simplifying your design. It is probably not necessary for nodes and edges to know about each other — a one way dependency should suffice.

And lastly, names containing double-underscores are reserved in C++ — you are not allowed to create such names in your own code.

月亮邮递员 2024-11-14 17:58:30

Edge.h

#ifndef EDGE_H_INCLUDED
#define EDGE_H_INCLUDED

class Node;

class Edge
{
    int edge_num;
public:
    Edge(int i) : edge_num(i) { };
    Node memberB();
};

#include "Node.h"  

Node Edge::memberB() { Node n(edge_num); return n; }
Node functionB()     { Node n(2);        return n; }

#endif /* EDGE_H_INCLUDED */

Node.h

#ifndef NODE_H_INCLUDED
#define NODE_H_INCLUDED

class Edge;

class Node
{
    int node_num;
public:
    Node(int i) : node_num(i) { };
    Edge memberA();
};

#include "Edge.h"

Edge Node::memberA() { Edge e(node_num); return e; }
Edge functionA()     { Edge e(1);        return e; }

#endif /* NODE_H_INCLUDED */

请注意,我在包含其他标头之前已向前声明了类“Edge”和“Node”,因此在定义函数或成员函数时,它返回的类也已定义。

Edge.h

#ifndef EDGE_H_INCLUDED
#define EDGE_H_INCLUDED

class Node;

class Edge
{
    int edge_num;
public:
    Edge(int i) : edge_num(i) { };
    Node memberB();
};

#include "Node.h"  

Node Edge::memberB() { Node n(edge_num); return n; }
Node functionB()     { Node n(2);        return n; }

#endif /* EDGE_H_INCLUDED */

Node.h

#ifndef NODE_H_INCLUDED
#define NODE_H_INCLUDED

class Edge;

class Node
{
    int node_num;
public:
    Node(int i) : node_num(i) { };
    Edge memberA();
};

#include "Edge.h"

Edge Node::memberA() { Edge e(node_num); return e; }
Edge functionA()     { Edge e(1);        return e; }

#endif /* NODE_H_INCLUDED */

Note that I have forward declared the classes 'Edge' and 'Node' before the other header is included, so that by the time the function or member function is defined, the class it returns is also defined.

拥抱没勇气 2024-11-14 17:58:30

您的包含守卫的问题是它们不匹配!

您测试 _SOMETHING (一个下划线),如果没有找到,则定义 __SOMETHING (两个下划线);这两个应该匹配,否则包含防护不起作用!

正如其他人指出的那样,避免以下划线开头,因为这些是为库和操作系统保留的。

The problem with your include guards is that they don't match!

You test for _SOMETHING (one underscore) and then if not found you define __SOMETHING (two underscores); these two should match else the include guard does not work!

As others have noted avoid starting things with underscores as those are reserved for libs and OS.

無心 2024-11-14 17:58:30

通过使用 pragma Guards 或 #pragma Once(后者,如果您的编译器支持的话)可以防止这种情况。

要使用编译指示防护,只需执行以下操作:

#ifndef SOME_IDENTIFIER
#define SOME_IDENTIFIER

// ... code ...

#endif

确保更改每个头文件的 SOME_IDENTIFIER。通常人们会使用NAME_OF_HEADER_H;如果您更改一个标识符,请确保同时更改该标识符的两个实例。

另外,如果您这样做,请确保您所做的任何 #include 都位于编译指示守卫的内部

如果您只想使用#pragma Once并且您的编译器支持它,则只需添加

#pragma once

到头文件的顶部即可。

另一方面,请考虑将函数 functionAfunctionB 的定义移动到它们自己的 .cpp 文件中,并仅在 .h 文件中保留原型,这样您就不需要获取链接器错误。

This is prevented by using either pragma guards or #pragma once (the latter if your compiler supports it).

To use pragma guards, simply do this:

#ifndef SOME_IDENTIFIER
#define SOME_IDENTIFIER

// ... code ...

#endif

Make sure to change SOME_IDENTIFIER for every header file. Usually people make it NAME_OF_HEADER_H; make sure you change both instances of the identifier if you change one.

Also if you do this, make sure any #includes you do are inside the pragma guards.

If you just want to use #pragma once and your compiler supports it, you just have to add

#pragma once

to the top of your header file.

On another note, consider moving the definition of the functions functionA and functionB to their own .cpp files and keeping just the prototype in the .h files, so you don't get linker errors.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文