我弄乱了我的遗产

时间:2011-06-14 17:35:47

标签: c++ inheritance constructor sfml

所以我有一个Piece类应该代表棋盘上的棋子,我计划从中继承另外两个类。不过,我在这方面遇到了很多问题;这是迄今为止的相关代码。

///
/// 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 个答案:

答案 0 :(得分: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);
}

基类的构造函数在构造函数之前运行(无论如何) - 如果初始化列表中需要参数,则需要将参数传递给它。

我不确定其他错误,因为我不知道它们正在发生哪些行。

答案 1 :(得分:4)

行中的括号

Piece(initial);
编译器忽略

。您正在声明一个与参数名称相同的变量:

Piece initial;

要使用Piece初始化initial基础对象,您必须使用成员初始化列表:

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

此外,Move函数需要两个参数,但您只传递一个参数。你忘记了布尔值。

答案 2 :(得分:1)

如果你想初始化超类,你应该这样做:

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

如果没有显式初始化基类型,编译器将尝试通过调用带有空参数列表的构造函数来初始化它,如下所示:

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

但是由于你没有为Piece定义一个零参数的构造函数,你会得到你描述的编译器错误。

答案 3 :(得分:1)

好的答案,全部。加上最后令人生畏的一线

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

是由

引起的

CurrentSpace.ToggleOccupied();

你已经声明CurrentSpace是一个指针,所以这应该是

CurrentSpace-&GT; ToggleOccupied();