问题描述
|
我对C ++的处理方式有些困惑。
我有类似的东西:
typedef struct {
//struct fields
} Vertex;
#include \"GenericObject.h\"
现在在GenericObject.h中,我有:
class GenericObject {
public:
Vertex* vertices;
}
当我尝试编译时,编译器会说:
ISO C ++禁止声明无类型的\'Vertex \'
如何获得GenericObject.h了解顶点?
我的印象是,包含文件中包含在#include之前定义的所有内容。
最后,您能否给我一些有关如何正确使用#include的提示,而不引入过多的冗余或循环包含。
谢谢。
解决方法
两件事,首先,您希望它只是...
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 \”。
,
我的印象是,包含文件中包含在#include之前定义的所有内容。
是的(所以我不确定您的代码在做什么),但是请不要依赖于此!标头应该是独立的,并且绝对不应该依赖标头在其“作用域”之外的其他文件中包含的内容。
(顺便说一句,此规则也适用于using
声明:不要在标头A中写using namespace std
,因为您可能会发现自己最终不小心依赖了标头B和C中包含标头A的内容!)
在使用Vertex
和#include
定义标题的地方。
如果只使用Vertex*
或Vertex&
,通常可以向前声明类型:struct Vertex;
。这有助于避免循环依赖。
, 要回答关于通函的第二个问题。
大多数人就是这样做的。例如包含header.h
#ifndef HEADER_H
#define HEADER_H
//you code here
#endif
, 解决此问题的一种方法是“转发声明”顶点结构:
//
// GenericObject.h
//
struct Vertex;
class GenericObject {
{
public:
Vertex *vertices;
};
请注意,此时“顶点”是一个“不完整的类型”,因此任何必须增大其大小或访问其成员的内容均不起作用。不过,您可以声明指向它们的指针。
, 冒着学究的风险,应将#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