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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6021720/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 19:21:26  来源:igfitidea点击:

C++ - Nested include - Avoiding 'include nested too deeply error'

c++nested-includes

提问by all_by_grace

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'?

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

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 对象的函数。对于 Edge 类,我有需要返回 Node 对象的函数。但是编译器不允许我有这个嵌套循环的东西。

Node.h

节点.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

边.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

采纳答案by all_by_grace

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:

所以 edge.h 应该像这样:

#ifndef EDGE_H
#define EDGE_H

class Node;    // forward declaration

Node functionB();

#endif

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

请注意,您必须在单独的 C++ 文件中定义您的函数,然后 #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.

最后,包含双下划线的名称在 C++ 中是保留的——你不能在你自己的代码中创建这样的名称。

回答by Jonathan Leffler

Edge.h

边.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

节点.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.

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

回答by RedX

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!

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

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

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

回答by Seth Carnegie

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

这可以通过使用编译指示守卫或#pragma once(后者,如果您的编译器支持它)来防止。

To use pragma guards, simply do this:

要使用 pragma 守卫,只需执行以下操作:

#ifndef SOME_IDENTIFIER
#define SOME_IDENTIFIER

// ... code ...

#endif

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

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

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

此外,如果您这样做,请确保#include您所做的任何s 都pragma 守卫内。

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

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

#pragma once

to the top of your header file.

到头文件的顶部。

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

另一方面,考虑将函数的定义functionAfunctionB它们自己的 .cpp 文件移动,并在 .h 文件中只保留原型,这样您就不会出现链接器错误。