繁体   English   中英

无效使用不完整的类型“类”

[英]Invalid use of incomplete type “class”

我知道有很多这样的问题,但是不幸的是,经过数小时的谷歌搜索和浏览所有问题之后,我读到的答案都无济于事。 因此,我正在制作自己的问题版本。 我得到的错误消息是:“错误:不完整类型'std :: iterator_traits :: value_type {aka class Cell}的无效使用'”我的代码:

单元格

#ifndef CELL_H
#define CELL_H

#include <QPushButton>
#include <QMouseEvent>
#include <vector>

class Padding;

class Cell : public QPushButton
{
    Q_OBJECT

    public:

        friend class Padding;
        Cell(int x, int y, Padding* padding, QWidget* parent = 0) : QPushButton(parent), x(x), y(y),
            padding(padding)
        {
            setFixedSize(20, 20);
        }
        Cell(const Cell& object) : QPushButton(), x(object.x), y(object.y), padding(object.padding)
        {
            setFixedSize(20, 20);
        }
        int getX() { return x; };
        int getY() { return y; };
        bool hasMine() { return mine; };
        void setHasMine(bool mine) { this -> mine = mine; };
        bool isFlagged() { return flagged; };
        bool didExplode() { return exploded; };
        bool getHasBeenClicked() { return hasBeenClicked; };
        void clicked();
        ~Cell() {};
        Cell operator=(const Cell& object)
        {
            if(&object == this)
            {
                return *this;
            }
            padding = object.padding;
            x = object.x;
            y = object.y;
            mine = object.mine;
            flagged = object.flagged;
            exploded = object.exploded;
            hasBeenClicked = object.hasBeenClicked;
            setFixedSize(20, 20);
            return *this;
        }

    private:

        Padding* padding;
        int x;
        int y;
        bool mine = false;
        bool flagged = false;
        bool exploded = false;
        bool hasBeenClicked = false;
        void mousePressEvent(QMouseEvent* e);
        void rightClicked();
};

#endif // CELL_H

单元格

#include "cell.h"
#include "padding.h"

void Cell::mousePressEvent(QMouseEvent* event)
{
    if(event -> button() == Qt::LeftButton)
    {
        clicked();
    }
    else if(event -> button() == Qt::RightButton)
    {
        rightClicked();
    }
}

void Cell::clicked()
{
    hasBeenClicked = true;
    // TODO: Set the button frame to flat. DONE.
    setFlat(true);
    // TODO: Make the button not click able. DONE.
    setEnabled(false);
    // TODO: Display appropriate number on the button, or mine and end the game. DONE.
    if(mine)
    {
        // TODO: Send game over signal and end the game.
        //setIcon(QIcon("mine_clicked.png"));
        setText("/");
        exploded = true;
        padding -> gameOver();
    }
    else
    {
        setText(QString::number(padding -> countMinesAround(this)));
    }
    if(padding -> countMinesAround(this) == 0)
    {
        // Trigger chain reaction; uncover many neighboring cells, if they are not mines.
        padding -> triggerChainReactionAround(this);
    }
}

void Cell::rightClicked()
{
    if(text() != "f")
    {
        setText("f");
        (padding -> minesLeft)--;
    }
    else
    {
        setText("");
        (padding -> minesLeft)++;
    }
    flagged = !flagged;
}

padding.h

#ifndef PADDING_H
#define PADDING_H

#include <QWidget>
#include <QGridLayout>
#include <vector>

class Cell;

class Padding : public QWidget
{
    Q_OBJECT

    public:

        friend class Cell;

        enum class Difficulty
        {
            Beginner,
            Intermediate,
            Advanced,
            Custom
        };

        Padding(QWidget* parent = 0);
        void newGame();
        void gameOver();
        void setLevel(Padding::Difficulty difficulty) { this -> difficulty = difficulty; };
        void setPaddingHeight(int height) { paddingHeight = height; };
        void setPaddingWidth(int width) { paddingWidth = width; };
        void setMines(int mines) { this -> mines = mines; };
        int getMinesLeft() { return minesLeft; };
        ~Padding() {};

    private:

        struct DifficultyLevelsProperties
        {
            struct BeginnerProperties
            {
                const int PADDING_HEIGHT = 9;
                const int PADDING_WIDTH = 9;
                const int MINES = 10;
            } Beginner;

            struct IntermediateProperties
            {
                const int PADDING_HEIGHT = 16;
                const int PADDING_WIDTH = 16;
                const int MINES = 40;
            } Intermediate;

            struct AdvancedProperties
            {
                const int PADDING_HEIGHT = 16;
                const int PADDING_WIDTH = 40;
                const int MINES = 99;
            } Advanced;
        } LevelProperties;

        Difficulty difficulty = Difficulty::Beginner;
        int paddingHeight;
        int paddingWidth;
        int mines;
        // Mines that are not flagged.
        int minesLeft;
        // Time in seconds since the game was started.
        int secondsSinceStart;
        std::vector<Cell> cells;
        QGridLayout* paddingLayout;
        const int CELLS_HEIGHT = 20;
        const int CELLS_WIDTH = 20;
        int countMinesAround(Cell*);
        void triggerChainReactionAround(Cell*);
        void updateSecondsSinceStart();
};

#endif // PADDING_H

padding.cpp

#include "padding.h"
#include <QGridLayout>
#include <QTimer>
#include <QTime>
#include <QDebug>
#include "cell.h"

Padding::Padding(QWidget* parent) : QWidget(parent)
{
    newGame();
    paddingLayout = new QGridLayout(this);
    paddingLayout -> setSpacing(0);
}

void Padding::newGame()
{
    if(difficulty == Padding::Difficulty::Beginner)
    {
        paddingHeight = LevelProperties.Beginner.PADDING_HEIGHT;
        paddingWidth = LevelProperties.Beginner.PADDING_WIDTH;
        mines = LevelProperties.Beginner.MINES;
    }
    else if(difficulty == Padding::Difficulty::Intermediate)
    {
        paddingHeight = LevelProperties.Intermediate.PADDING_HEIGHT;
        paddingWidth = LevelProperties.Intermediate.PADDING_WIDTH;
        mines = LevelProperties.Intermediate.MINES;
    }
    else if(difficulty == Padding::Difficulty::Advanced)
    {
        paddingHeight = LevelProperties.Advanced.PADDING_HEIGHT;
        paddingWidth = LevelProperties.Advanced.PADDING_WIDTH;
        mines = LevelProperties.Advanced.MINES;
    }
    minesLeft = mines;
    cells.clear();
    for(int i = 0; i < paddingHeight; i++)
    {
        for(int j = 0; j < paddingWidth; j++)
        {
            // TODO: Use smart pointers instead of raw pointers.
            Cell* cell = new Cell(j + 1, i + 1, this);
            cells.push_back(*cell);
            delete cell;
        }
    }
    qsrand(QTime::currentTime().msec());
    for(int i = 0; i < mines; i++)
    {
        // TODO: Fix the randomness of the numbers. DONE.
        cells[qrand() % (paddingHeight * paddingWidth) + 1].setHasMine(true);
    }
    for(int i = 0; i < cells.size(); i++)
    {
        paddingLayout -> addWidget(&cells[i], cells[i].getY(), cells[i].getX());
    }
}

void Padding::gameOver()
{
    for(int i = 0; i < cells.size(); i++)
    {
        cells[i].setEnabled(false);
        if((cells[i].hasMine()) && (!cells[i].getHasBeenClicked()))
        {
            cells[i].clicked();
        }
    }
}

int Padding::countMinesAround(Cell*)
{
    int minesCounter = 0;
    for(int i = 0; i < cells.size(); i++)
    {
        qDebug() << QString::number(cells[i].getX());
        if(((x - cells[i].getX() == 0) || (x - cells[i].getX() == 1) || (x -
            cells[i].getX() == -1)) && ((y - cells[i].getY() == 0) || (y -
            cells[i].getY() == 1) || (y - cells[i].getY() == -1)) &&
            (cells[i].hasMine()))
        {
            minesCounter++;
        }
    }
    return minesCounter;
}

void Padding::triggerChainReactionAround(Cell*)
{
    for(int i = 0; i < cells.size(); i++)
    {
        if(((x - cells[i].getX() == 0) || (x - cells[i].getX() == 1) || (x -
            cells[i].getX() == -1)) && ((y - cells[i].getY() == 0) || (y -
            cells[i].getY() == 1) || (y - cells[i].getY() == -1)) &&
            (!cells[i].getHasBeenClicked()))
        {
            cells[i].clicked();
        }
    }
}

抱歉,整件事持续了多长时间,但由于无法找到导致错误的原因,因此无法缩短它的时间。 另外,请忽略任何待办事项或任何注释掉的行,而我忘记删除它们。 请帮忙!

转发声明类型时,只能使用指向该类型对象的指针引用 ,因此padding.h中的这一行几乎没有编译:

std::vector<Cell> cells;

我想编译器的抱怨来自试图确定如何在向量中构建/销毁Cell对象的地方。 为此,通常需要从类型声明(即头文件)中获取有关类型的信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM