编译错误,“使用未定义的结构”

时间:2013-01-12 22:06:16

标签: c++ struct

我想转发声明结构的各个部分,因此首先显示“package”结构。我收到“使用undefined struct”的错误,其中“Header”在“Package”中声明。当然,编译器(VS2010)会在抛出此错误之前扫描头文件中的定义吗?

struct Header;

struct Package
{
    Header header;             <-- "uses undefined struct"

};

struct Header
{
    uint32_t Signature;
    uint8_t MajorVersion;
    uint8_t MinorVersion;
};

由于

4 个答案:

答案 0 :(得分:7)

  

我收到“使用undefined struct”的错误,其中“Header”在“Package”中声明。

您不能声明不完整类型的成员,因为编译器不知道它有多大以及它应该为它保留多少空间(除其他外)。

  

在抛出此错误之前,编译器(VS2010)肯定会扫描头文件中的定义吗?

不,是什么让你这么想?

答案 1 :(得分:2)

当编译器还不知道Header究竟是什么时,你不能让Package包含Header类型的东西。你只能有指向标题的指针。

答案 2 :(得分:2)

在完全声明之前不能使用该类型,因为需要预先知道诸如大小等信息。但是,您可以指向这些类型,因为它们不需要此信息。


有两种方法可以解决这个问题。一个骗子和一个“适当的”。

首先是骗子。您可以对结构进行原型化,但是,在声明结构之前,您只能使用结构作为指针。因此,在声明之前,您不能将Header用作值类型。因此,欺骗性的方法是用Header header;替换Header *header;,然后在运行时分配内存。

然而,有一种更好,更好的方式。

您可以将此单个文件拆分为多个文件,即:header.hpppackage.hpp,并将它们包括在一起。但是,这样做有一个问题。当标题递归地包含彼此(或者您多次包含相同的标题)时,将一次又一次地重新设置类型。您需要一种仅定义类型一次的方法。几乎每次使用标题时都会这样做,方法是用“包含保护”将其括起来。它看起来像这样:

#ifndef HEADER_HPP
#define HEADER_HPP

// Header code here

#endif /* HEADER_HPP */

这样,它们只会被声明一次,但你可以在两个文件中使用这两种类型。

因此,您的package.hpp文件将如下所示:

#ifndef PACKAGE_HPP
#define PACKAGE_HPP

#include "header.hpp"

struct Package {
    Header header;
};

#endif

您的header.hpp将如下所示:

#ifndef HEADER_HPP
#define HEADER_HPP

struct Header {
    uint32_t Signature;
    uint8_t MajorVersion;
    uint8_t MinorVersion;
};

#endif

答案 3 :(得分:0)

您可以使用指针:

struct Package
{
    struct Header *header;
};

struct Header
{
    uint32_t Signature;
    uint8_t MajorVersion;
    uint8_t MinorVersion;
};