2

したがって、ボード上のピースを表す Piece クラスがあり、そこから他の 2 つのクラスを継承する予定です。ただし、そうすることで多くの問題が発生しました。これまでの関連コードは次のとおりです。

///
/// PIECE CLASS HERE
/// this is an abstract class from which Barrier and Pawn inherit.

class Piece
{
public:
    Piece(Space* start);
    sf::Shape m_Circle;
protected:
    int m_X;
    int m_Y;
    int m_radius;
    Space* CurrentSpace;
};

Piece::Piece(Space* start):
    m_X(start->GetX()),
    m_Y(start->GetY()),
    m_radius(14),
    CurrentSpace(start)
{}

///
/// BARRIER CLASS HERE
/// these are the white stones that block a player's path

class Barrier : public Piece
{
public:
    Barrier(Space* initial);
    void Move(Space* target, bool isCapturing);
};

Barrier::Barrier(Space* initial)
{
    Piece(initial);
    m_Circle = sf::Shape::Circle((float)m_X, (float)m_Y, (float)m_radius, sf::Color(255, 255, 255));
    Move(initial);
}

void Barrier::Move(Space* target, bool isCapturing)
{
    int xChange = abs(target->GetX() - m_X);
    int yChange = abs(target->GetY() - m_Y);
    m_Circle.Move((float)xChange, (float)yChange);
    CurrentSpace.ToggleOccupied();
    if(!isCapturing)
    {
        (*target).ToggleOccupied();
    }
    CurrentSpace = target;
}

特に、理解できないエラーが大量に発生します。

no matching function for call to Piece::Piece()
declaration of 'Piece initial' shadows a parameter
no matching function for call to 'Barrier::Move(Piece&)'
request for member 'ToggleOccupied' in '((Barrier*)this)->Barrier::<anonymous>.Piece::CurrentSpace', which is of non-class type 'Space*'|

C++ は初めてなので、何が問題なのかわかりません。C++ の学習に使用した本で見つけたコードに類似したコードを作成しようとしましたが、明らかに微妙な点を見落としていました。呼び出そうとする関数はすべて適切な場所にあるようで、プロトタイプと同じ値で定義していると思います。

4

4 に答える 4

12

最初のエラーはこれが原因です:

Barrier::Barrier(Space* initial)
{
    Piece(initial);
    m_Circle = sf::Shape::Circle((float)m_X, (float)m_Y, (float)m_radius, sf::Color(255, 255, 255));
    Move(initial);
}

次のようにする必要があります。

Barrier::Barrier(Space* initial) : Piece(initial)
{
    m_Circle = sf::Shape::Circle((float)m_X, (float)m_Y, (float)m_radius, sf::Color(255, 255, 255));
    Move(initial);
}

基本クラスのコンストラクターは、コンストラクターの前に実行されます (何があっても)。初期化リストに引数が必要な場合は、引数を渡す必要があります。

どの行で発生しているかがわからないため、他のエラーについてはわかりません。

于 2011-06-14T17:38:34.040 に答える
4

行の括弧

Piece(initial);

コンパイラによって無視されます。パラメータと同じ名前の変数を宣言しています。

Piece initial;

Pieceでベース オブジェクトを初期化するinitialには、メンバー初期化子リストを使用する必要があります。

Barrier::Barrier(Space* initial) : Piece(initial)

また、Move関数は 2 つの引数を想定していますが、渡すのは 1 つだけです。ブール値を忘れました。

于 2011-06-14T17:39:47.437 に答える
1

スーパー クラスを初期化する場合は、次のようにします。

Barrier(Space* initial): 
    Piece(initial) {
    ...
}

基本型を明示的に初期化しない場合、コンパイラは次のように、空の引数リストを使用してコンストラクターを呼び出して初期化を試みます。

Barrier(Space* initial):
    Piece() {
    ... 
}

しかし、ゼロの引数を取る Piece のコンストラクターを定義していないため、説明したコンパイラ エラーが発生します。

于 2011-06-14T17:39:23.363 に答える
1

良い答えです。さらに、その最後の困難な行

request for member 'ToggleOccupied' in '((Barrier*)this)->Barrier::<anonymous>.Piece::CurrentSpace', which is of non-class type 'Space*'|

から引き起こされている

CurrentSpace.ToggleOccupied();

CurrentSpace をポインターとして宣言したので、これは次のようになります。

CurrentSpace->ToggleOccupied();

于 2011-06-14T17:45:51.960 に答える