1

我想前向声明结构的各个部分,因此首先显示“包”结构。我收到“使用未定义结构”的错误,其中“包”中声明了“标头”。编译器(VS2010)肯定会在抛出此错误之前扫描头文件中的定义吗?

struct Header;

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

};

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

谢谢

4

4 回答 4

8

我收到“使用未定义结构”的错误,其中“包”中声明了“标头”。

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

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

不,是什么让你这么想?

于 2013-01-12T22:11:00.413 回答
3

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


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

首先是骗子。您可以对结构进行原型设计,但是,在声明它之前,您只能将结构用作指针。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
于 2013-01-12T22:15:56.200 回答
2

当编译器还不知道 Header 到底是什么时,你不能让 Package 包含 Header 类型的东西。您只能拥有指向 Header 的指针。

于 2013-01-12T22:08:45.667 回答
1

您可以使用指针:

struct Package
{
    struct Header *header;
};

struct Header
{
    uint32_t Signature;
    uint8_t MajorVersion;
    uint8_t MinorVersion;
};
于 2020-04-19T03:22:57.430 回答