エラー: 'xxx' は、前方宣言と C++ ヘッダー ファイルの相互包含によって引き起こされる型の問題を示していません

ソース ファイルでクラスへのポインターを宣言または定義する場合は、クラスを使用する前に宣言または定義する必要があるため、次のコードはエラーを報告します。

class A
{
public:
    B *b;
};

class B
{
public:
    A *a;
};

int main()
{
    return 0;
}


クラス A で B *b を使用する前にクラス B の宣言または定義がないため、「エラー: 'B' は型の名前がありません」というエラーが発生します。前方宣言 (前方宣言) を追加すると、「class B;」となります。 、そのような問題は発生しません。
ヘッダー ファイルが相互にインクルードされている場合、「エラー: 'xxx' は型の名前がありません」もトリガーされます。エラーの理由は上記のコードと同じです。次のコードを参照してください: ah
:

#ifndef A_H_INCLUDED
#define A_H_INCLUDED

#include "b.h"

class A
{
public:
    B *b;
};

#endif // A_H_INCLUDED


ば:

#ifndef B_H_INCLUDED
#define B_H_INCLUDED

#include "a.h"

class B
{
public:
    A *a;
};

#endif // B_H_INCLUDED


main.cpp:

#include "a.h"
#include "b.h"

int main()
{
    return 0;
}


コンパイルでは、「エラー: 'A' は型の名前がありません」というエラーが報告されます。なぜこれが起こるのでしょうか? 前処理後に ah がどのように展開されるかを見てみましょう。前処理コマンドは「gcc -E -o ai ah」です。

# 1 "a.h"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "a.h"

# 1 "b.h" 1

# 1 "a.h" 1
# 5 "b.h" 2

class B
{
public:
    A *a;
};
# 5 "a.h" 2

class A
{
public:
    B *b;
};


「#」で始まる行を無視すると、先頭のソースファイルとほぼ同じになっていますが、クラスの順序が入れ替わっているため、エラーの原因は先頭のソースファイルと同じです。始まり。
解決策も非常に簡単で、ah の「#include "bh"」をクラス B の事前宣言「class B;」に置き換え、bh に同様の変更を加えます。そうすれば問題は起こりません。もちろん、これを行うには前提条件があります: クラス A のメンバーはクラス B へのポインターのみを持ちますが、クラス B の変数を持つことはできません。同時に、ヘッダー ファイル内のクラス B のメンバーまたはメンバー関数にはアクセスできません。クラスAの。どちらの場合も、クラス A はクラス B のサイズなどの詳細を知る必要がありますが、前方宣言ではこれらの詳細を提供できず、「エラー: フィールド 'b' には不完全な型 'B' があります」のような問題が発生します。
 

おすすめ

転載: blog.csdn.net/weixin_58045467/article/details/130722016