我对C ++如何处理包含有点困惑。
我有类似的东西:
typedef struct {
//struct fields
} Vertex;
#include "GenericObject.h"
现在在GenericObject.h中我有:
class GenericObject {
public:
Vertex* vertices;
}
当我尝试编译时,编译器说:
ISO C ++禁止声明“Vertex”没有类型
如何让GenericObject.h了解Vertex?
我的印象是在#include之前定义的任何内容都可以在包含的文件中找到。
最后,你能否给我一些关于如何正确使用#include而不引入太多冗余或循环包含的提示。
感谢。
答案 0 :(得分:9)
两件事,首先你要它只是......
struct Vertex
{
//struct fields
};
这是C ++中正确定义的结构。 现在您需要在通用对象标题中包含Vertex.h,或者包含顶点结构的文件,
#include "Vertex.h"
class GenericObject {
public:
Vertex* vertices;
};
或者向前声明它......
struct Vertex;
class GenericObject {
public:
Vertex* vertices;
};
不要从“Vertex.h”#include“GenericObject.h”。
答案 1 :(得分:3)
我的印象是在#include之前定义的任何内容都可以在包含的文件中找到。
是的(所以我不确定你的代码会发生什么),但是请不要依赖它!。标题应该是自包含的,并且绝对不依赖于它之前的其他文件中包含的内容,超出其“范围”。
(另外,此规则也适用于using
声明:在标题A中不写using namespace std
,因为您可能会发现您最终意外地依赖从你的标题B和C出现,包括标题A!)
您使用Vertex
,#include
定义它的标头。
仅使用Vertex*
或Vertex&
的地方,通常只需向前声明类型:struct Vertex;
。这有助于避免循环依赖。
答案 2 :(得分:1)
回答关于循环包含的第二个问题。 这就是大多数人这样做的方式。例如,包括header.h
#ifndef HEADER_H
#define HEADER_H
//you code here
#endif
答案 3 :(得分:0)
解决这个问题的一种方法是“向前声明”顶点结构:
//
// GenericObject.h
//
struct Vertex;
class GenericObject {
{
public:
Vertex *vertices;
};
此时请注意,Vertex是一个“不完整类型”,因此任何必须占用其大小或访问其成员的内容都不起作用。但是,您可以声明指向它们的指针。
答案 4 :(得分:0)
冒着迂腐的风险,你应该将#include
指令放在翻译单元的顶部。然后你可以:
// File vertex.h
#ifndef VERTEX_H
#define VERTEX_H
struct Vertex { ... };
#endif
和
// File gobject.h
#ifndef GOBJECT_H
#define GOBJECT_H
#include "vertex.h"
class GObject { ... }; // Use Vertex structures here
#endif
或者,正如所指出的,您可以提前声明Vertex
结构:
// File gobject.h
#ifndef GOBJECT_H
#define GOBJECT_H
struct Vertex; // Declaration of a struct named Vertex
class GObject { ... }; // Use Vertex structures here
#endif