我想转发声明结构的各个部分,因此首先显示“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;
};
由于
答案 0 :(得分:7)
我收到“使用undefined struct”的错误,其中“Header”在“Package”中声明。
您不能声明不完整类型的成员,因为编译器不知道它有多大以及它应该为它保留多少空间(除其他外)。
在抛出此错误之前,编译器(VS2010)肯定会扫描头文件中的定义吗?
不,是什么让你这么想?
答案 1 :(得分:2)
当编译器还不知道Header究竟是什么时,你不能让Package包含Header类型的东西。你只能有指向标题的指针。
答案 2 :(得分:2)
在完全声明之前不能使用该类型,因为需要预先知道诸如大小等信息。但是,您可以指向这些类型,因为它们不需要此信息。
有两种方法可以解决这个问题。一个骗子和一个“适当的”。
首先是骗子。您可以对结构进行原型化,但是,在声明结构之前,您只能使用结构作为指针。因此,在声明之前,您不能将Header
用作值类型。因此,欺骗性的方法是用Header header;
替换Header *header;
,然后在运行时分配内存。
您可以将此单个文件拆分为多个文件,即:header.hpp
和package.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;
};