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

サイズなどの情報が事前にわかっている必要があるため、完全に宣言されるまで型を使用することはできません。ただし、これらの型はこの情報を必要としないため、これらの型へのポインターを作成することはできます。


これを解決するには 2 つの方法があります。チートなものと「適切な」もの。

最初にチートなもの。構造体のプロトタイプを作成することはできますが、宣言するまで構造体をポインターとしてしか使用できません。Headerしたがって、宣言される前に値型として使用することはできません。したがって、不正な方法は、実行時にメモリを置き換えHeader header;て割り当てることです。Header *header;

ただし、はるかに優れた方法があります。

この単一のファイルを複数のファイル、つまりheader.hppとに分割package.hppし、それらに相互を含めることができます。ただし、これを行う際に 1 つの問題があります。ヘッダーが相互に再帰的にインクルードする (または同じヘッダーを複数回インクルードする) 場合、型は何度も再定義されます。タイプを一度だけ定義する方法が必要です。これは、ヘッダーが使用されるたびに、「包含ガード」で囲むことによって行われます。次のようになります。

#ifndef HEADER_HPP
#define HEADER_HPP

// Header code here

#endif /* HEADER_HPP */

そうすれば、それらは 1 回だけ宣言されますが、両方のファイルで両方の型を使用できます。

したがって、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 型の何かを含めることはできません。ヘッダーへのポインターのみを持つことができます。

于 2013-01-12T22:08:45.667 に答える