在类的构造函数中初始化由向量组成的矩阵。

6

我正在尝试构建一个具有字符矩阵的游戏。我正在尝试使用向量的向量来构建我的矩阵。我的 game.h 文件如下:

#ifndef GAME_H
#define GAME_H
// includes
using namespace std;
class Game 
{
  private:
    int row;
    int col;
    vector<vector<char>>* matrix;
    // other atributtes

  public:
    Game();
    ~Game(){}
    // some functions
};
#endif

在我的game.cpp文件中:

Game::Game()
{
    this->col = 20;
    this->row = 20;
    // Initialize the matrix
    this->matrix = new vector<vector<char>>(this->col);
    for(int i = 0 ; i < this->col ; i++)
       this->matrix[i].resize(this->row, vector<char>(row));
    // Set all positions to be white spaces
    for(int i = 0 ; i <  this->col; i++)
      for(int j = 0 ; j < this->row ; j++)
        this->matrix[i][j] = ' ';
}

它给我一个错误:

error: no match for ‘operator=’ (operand types are ‘__gnu_cxx::__alloc_traits<std::allocator<std::vector<char> > >::value_type {aka std::vector<char>}’ and ‘char’)
     this->matrix[i][j] = ' ';
                          ^~~

在这行代码中:
this->matrix[i][j] = ' ';

我想知道是什么导致了这个问题,以及如何在我的构造函数中将所有内容设置为空格。

你真的应该避免使用 using namespace std - 这是一个不好的习惯,当你不期望时,它会悄悄地改变你程序的含义。要习惯使用命名空间前缀(std 故意非常短),或者将仅需要的名称导入到最小合理范围中。在头文件中尤其有害,因为现在你将问题强加给了包括头文件的每个源文件! - Toby Speight
顺便问一下,你读了错误信息吗?你正在尝试将char赋值给类型为std::vector<char>的对象。也许你想让matrix成为一个向量的向量,而不是一个指向向量的指针。 - Toby Speight
即使您设法调整并使上述代码工作,依我看来,隐式“this”对象的多次取消引用将损害性能。其次,您的for循环中的循环索引类型int与std :: vector <T>类所需的循环索引不匹配(如果它仍然存在的话:P),这将再次导致隐式转换,进一步减缓代码速度。 - ggulgulia
2个回答

5

this->matrix的类型是std::vector<std::vector<char>>*

this->matrix[i]的类型是std::vector<std::vector<char>>

this->matrix[i][j]的类型是std::vector<char>

因此,

this->matrix[i][j] = ' ';

无法正常工作。

简化您的代码。将 matrix 更改为

std::vector<std::vector<char>> matrix; // Remove the pointer

根据需要调整你的代码。


非常感谢您! - Carlos A. Jimenez Holmquist
你可能想要提到这个事实,即使用this->matrix = new vector<vector<char>>(this->col)将无法编译通过。 - Peter
@Peter,我想OP已经明白了,因为他接受了答案。 - R Sahu

1
假如我是你,我会这样做:
在 games.hpp 文件中:
#ifndef GAME_H
#define GAME_H
// includes
template <class T>
class Game : public std::vector<std::vector<T>>
{
     private:
        int row;
        int col;

    public:
        Game();
       ~Game(){}
// some functions
};
#endif

在 games.cpp 中
template<class T>
Game<T>::Game(int rr=20, int cc=20):
    row(rr), col(cc), std::vector<std::vector<T>>(rr, std::vector<T>(cc))
{
 //empty body   
}

这自然会使您访问元素的方式变得更加复杂,但是可以通过重载返回您想要访问的位置的引用的operator()轻松完成。请注意,通过公开继承std::vector,我们继承了它们所有的运算符、成员函数和变量。因此,我们还继承了std::vector类中重载的operator[]。因此,我们可以通过重载的运算符访问任何元素,如下所示:

template<class T>
T& Game<T>::operator()(int rr, int cc){
return this->operator[](rr)[cc];
}

在上面的返回语句中,第一部分使用参数rr调用重载的operator[],它返回一个vector对象,然后我们再次调用重载的operator[]来调用列索引'cc'的参数(就像我们使用std::vector object[index]一样)。这样代码看起来肯定更加优雅和专业 :)

对于可扩展的代码,我会使用 'size_t' 而不是 'int' 作为行和列的类型,或者更好地定义一个新的类型名 'size_type',这是 std::vector<T> 在其定义中使用的(请查看 cpp reference)以及下面的链接 https://dev59.com/rmMl5IYBdhLWcg3wc2xp - ggulgulia
谢谢!好的解决方案! - Carlos A. Jimenez Holmquist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接