web-dev-qa-db-ja.com

c ++「不完全な型は許可されていません」クラス参照情報へのアクセスエラー(前方宣言による循環依存関係)

最近、循環依存として認識していることを取り巻くコードにいくつかの問題がありました。つまり、PlayerとBallの2つのクラスがあり、どちらも他方の情報を使用する必要があります。コードのある時点で、両方に他の参照が渡されます(両方の.hファイルを含む別のクラスから)。

それを読んだ後、各ファイルから#include.hファイルを削除し、前方宣言を行いました。これにより、クラスを相互に宣言できるという問題は解決しましたが、オブジェクトに渡された参照にアクセスしようとすると、「不完全な型エラー」が残ります。多くの場合、より複雑なコードと混ざっており、基本に絞り込むのは難しいですが、いくつかの類似した例があるようです。

コードを最も単純な形式(本質的にはスケルトン)に書き直しました。

Ball.h:

class Player;

class Ball {
public:
    Player& PlayerB;
    float ballPosX = 800;
private:

};

Player.h:

class Ball;

class Player {
public:
    void doSomething(Ball& ball);
private:
};

Player.cpp:

#include "Player.h"

void Player::doSomething(Ball& ball) {
    ball.ballPosX += 10;                   // incomplete type error occurs here.
}

これが事実である理由を理解する助けは大歓迎です:)

29
nat1707828

定義をこの順序で配置すると、コードがコンパイルされます

class Ball;

class Player {
public:
    void doSomething(Ball& ball);
private:
};

class Ball {
public:
    Player& PlayerB;
    float ballPosX = 800;
private:

};

void Player::doSomething(Ball& ball) {
    ball.ballPosX += 10;                   // incomplete type error occurs here.
}

int main()
{
}

関数doSomethingの定義には、そのデータメンバーにアクセスするため、Ballクラスの完全な定義が必要です。

コード例モジュールでは、Player.cppはBallクラスの定義にアクセスできないため、コンパイラはエラーを発行します。

20

Player.cppには、Ballクラスの定義が必要です。したがって、#include "Ball.h"を追加するだけです

Player.cpp:

#include "Player.h"
#include "Ball.h"

void Player::doSomething(Ball& ball) {
    ball.ballPosX += 10;                   // incomplete type error occurs here.
}
15
Nima Soroush

ここに私が持っていたものと私の「不完全な型エラー」の原因があります:

#include "X.h" // another already declared class
class Big {...} // full declaration of class A

class Small : Big {
    Small() {}
    Small(X); // line 6
}
//.... all other stuff

ファイル「Big.cpp」で行ったことは、XをパラメーターとしてA2のコンストラクターを宣言したことです。

Big.cpp

Small::Big(X my_x) { // line 9 <--- LOOK at this !
}

「Small :: Small」の代わりに「Small :: Big」と書いた、なんて馬鹿げた間違いなのか。クラスXで常に「不完全な型が許可されている」というエラーを受け取った( 6行目と9行目、これは完全な混乱を引き起こしました。

とにかく、それは間違いが発生する可能性のある場所であり、主な理由は、私がそれを書いたときに疲れていて、それを明らかにするためにコードを探索して書き換えるのに2時間必要だったからです。

2
Casper