如果我想在我的C ++代码中使用以下连接,那么声明我的头文件的最佳方法是什么,只是为了让我没有得到'包含嵌套太深的错误'?
在我的edge类中,我有一些需要返回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
答案 0 :(得分:11)
正如其他人所建议的那样,使用标题保护。但也尝试声明有问题的类。您可能还必须在至少一个类中使用指针(而不是值),但是在没有看到代码的情况下,我们无法分辨。
所以edge.h应该像:
#ifndef EDGE_H
#define EDGE_H
class Node; // forward declaration
Node functionB();
#endif
请注意,您必须在单独的C ++文件中定义您的函数,然后#includes“node.h”。
如果这一切看起来非常复杂,那么您应该尝试简化您的设计。节点和边缘可能没有必要相互了解 - 单向依赖应该足够了。
最后,包含双下划线的名称在C ++中保留 - 您不能在自己的代码中创建此类名称。
答案 1 :(得分:5)
#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 */
#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',因此在定义函数或成员函数时,它还返回了它返回的类。
答案 2 :(得分:3)
使用pragma guards或#pragma once
(后者,如果你的编译器支持它)可以防止这种情况。
要使用pragma guards,只需执行以下操作:
#ifndef SOME_IDENTIFIER
#define SOME_IDENTIFIER
// ... code ...
#endif
确保为每个头文件更改SOME_IDENTIFIER
。通常人们会NAME_OF_HEADER_H
;确保在更改标识符时更改标识符的两个实例。
此外,如果你这样做,请确保你所做的任何#include
在中的
名护卫。
如果您只想使用#pragma once
并且您的编译器支持它,您只需要添加
#pragma once
到头文件的顶部。
另外请注意,考虑将函数functionA
和functionB
的定义移动到它们自己的.cpp文件中,并将原型保留在.h文件中,这样就不会出现链接器错误
答案 3 :(得分:3)
包含警卫的问题是它们不匹配!
您测试_SOMETHING
(一个下划线)然后如果找不到则定义__SOMETHING
(两个下划线);这两个应该匹配,否则包含后卫不起作用!
正如其他人所指出的那样,避免以下划线开始,因为它们是为libs和OS保留的。