管理C ++ include指令的正确方法

时间:2011-05-31 17:08:05

标签: c++ include

我对C ++如何处理包含有点困惑。

我有类似的东西:

typedef struct {
  //struct fields
} Vertex;

#include "GenericObject.h"

现在在GenericObject.h中我有:

class GenericObject {
  public:
    Vertex* vertices; 
}

当我尝试编译时,编译器说:

  

ISO C ++禁止声明“Vertex”没有类型

如何让GenericObject.h了解Vertex?

我的印象是在#include之前定义的任何内容都可以在包含的文件中找到。

最后,你能否给我一些关于如何正确使用#include而不引入太多冗余或循环包含的提示。

感谢。

5 个答案:

答案 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