c++ 类:在公共函数中使用私有数组?

Posted

技术标签:

【中文标题】c++ 类:在公共函数中使用私有数组?【英文标题】:c++ class: using a private array in a public function? 【发布时间】:2015-04-02 07:42:54 【问题描述】:

这是我在头文件中使用的代码:

#ifndef TETRIS_TETRIMINO
#define TETRIS_TETRIMINO

const int TETRIMINO_GRID_SIZE = 4;

struct Location 
    int row;
    int col;
;

class Tetrimino 
private:
    int grid[TETRIMINO_GRID_SIZE][TETRIMINO_GRID_SIZE];
    char color;
    Location location;
public:
    // constructor
    Tetrimino(int type = 7); // valid type values are 0-6

//---------------------------------------------
//accessors
    char getColor();
    Location getLocation();
    void getGrid(int gridOut[][TETRIMINO_GRID_SIZE]);

//---------------------------------------------
//mutators
    void setLocation(Location newLocation);
    void setLocation(int row, int col);

    void rotateLeft();
    void rotateRight();
    void moveLeft();
    void moveRight();
    void moveDown();
    void moveUp();

//---------------------------------------------
//others
    void dataDump();
    ;
    #endif

这是.cpp:

#include "tetrimino.h"
#include <iostream>
#include <ctime>
using namespace std;

//random number generator
int randNum()

    int randNum;
    int high = 6;
    int low = 0;
    srand(static_cast<unsigned int>(time(NULL)));
    randNum = rand() % (high - low + 1) + low;
    return randNum;



Tetrimino::Tetrimino(int type)

    //check to see if type is 0-6, if not set to 7
    if (type < 0 || type >= 7)
    
        type = randNum();
    

    //set associated type to a tetrimino
    if (type == 0)
    
        //set grid to i tetro
        int grid[TETRIMINO_GRID_SIZE][TETRIMINO_GRID_SIZE] =
        
             0, 0, 0, 0 ,
             1, 1, 1, 1 ,
             0, 0, 0, 0 ,
             0, 0, 0, 0 
        ;
        //set color to teal
        color = 't';

        //initialize starting position
        location.row = 0;
        location.col = 0;
    
    else if (type == 1)
    
        //set grid to j tetro
        int grid[TETRIMINO_GRID_SIZE][TETRIMINO_GRID_SIZE] =
        
             0, 0, 0, 0 ,
             0, 1, 0, 0 ,
             0, 1, 1, 1 ,
             0, 0, 0, 0 
        ;
        //set color to blue
        color = 'b';

        //initialize starting position
        location.row = 0;
        location.col = 0;
    
    else if (type == 2)
    
        //set grid to L tetro
        int grid[TETRIMINO_GRID_SIZE][TETRIMINO_GRID_SIZE] =
        
             0, 0, 0, 0 ,
             0, 0, 1, 0 ,
             1, 1, 1, 0 ,
             0, 0, 0, 0 
        ;
        //set color to orange
        color = 'o';

        //initialize starting position
        location.row = 0;
        location.col = 0;
    
    else if (type == 3)
    
        //set grid to o tetro
        int grid[TETRIMINO_GRID_SIZE][TETRIMINO_GRID_SIZE] =
        
             0, 0, 0, 0 ,
             0, 1, 1, 0 ,
             0, 1, 1, 0 ,
             0, 0, 0, 0 
        ;
        //set color to yellow
        color = 'y';

        //initialize starting position
        location.row = 0;
        location.col = 0;
    
    else if (type == 4)
    
        //set grid to s tetro
        int grid[TETRIMINO_GRID_SIZE][TETRIMINO_GRID_SIZE] =
        
             0, 0, 0, 0 ,
             0, 1, 1, 0 ,
             1, 1, 0, 0 ,
             0, 0, 0, 0 
         ;
        //set color to green
        color = 'g';

        //initialize starting position
        location.row = 0;
        location.col = 0;
    
    else if (type == 5)
    
        //set grid to T tetro
        int grid[TETRIMINO_GRID_SIZE][TETRIMINO_GRID_SIZE] =
        
             0, 0, 0, 0 ,
             0, 1, 0, 0 ,
             1, 1, 1, 0 ,
             0, 0, 0, 0 
        ;
        //set color to purple
        color = 'p';

        //initialize starting position
        location.row = 0;
        location.col = 0;
    
    else if (type == 6)

    //set grid to z tetro
    int grid[TETRIMINO_GRID_SIZE][TETRIMINO_GRID_SIZE] =
    
         0, 0, 0, 0 ,
         0, 1, 1, 0 ,
         0, 0, 1, 1 ,
         0, 0, 0, 0 
    ;
    //set color to red
    color = 'r';

    //initialize starting position
    location.row = 0;
    location.col = 0;

  ;

  //accessors
  char Tetrimino::getColor()
  
      return color;
  
  Location Tetrimino::getLocation()
  
      return location;
  
  void Tetrimino::getGrid(int gridOut[][TETRIMINO_GRID_SIZE])
  
      //loop goes through each row
      for (int row = 0; row < TETRIMINO_GRID_SIZE; row++)
      
          //goes through each col of current row
          for (int column = 0; column < TETRIMINO_GRID_SIZE; column++)
          
              cout << gridOut[row][column] << " ";
          
          //new line between rows
          cout << endl;
      
  

//mutators
//leaving these out of this for sanity

  void main()
  
      Tetrimino test(0);

      cout << test.getColor() << endl;
      test.getGrid(test.grid);

  

好的,显然代码不完整。我对如何使用公共函数 getGrid 从 Tetrimino 类中打印出网格数组感到非常困惑和困惑。头文件是预制给我的(虽然我理解)所以我不想编辑它。为什么 getGrid 函数首先需要一个参数?

我不能像在 main() 中那样简单地调用我想要打印的网格,因为它是私有的。我真的……是的,我知道这是错误的,但我不知道如何正确地去做。

编辑/更新: 我从 getGrid() 中删除了参数,并将 gridOut 更改为函数中的简单网格。但是,当我使用 test.getGrid() 调用函数时,打印的数组是:

-858993460 -858993460 -858993460 -858993460
-858993460 -858993460 -858993460 -858993460
-858993460 -858993460 -858993460 -858993460
-858993460 -858993460 -858993460 -858993460

我更改的代码是:

void Tetrimino::getGrid()

    //loop goes through each row
    for (int row = 0; row < TETRIMINO_GRID_SIZE; row++)
    
        //goes through each col of current row
        for (int column = 0; column < TETRIMINO_GRID_SIZE; column++)
        
            cout << grid[row][column] << " ";
        
        //new line between rows
        cout << endl;
    

getGrid 已更改为网格。

我现在这样调用函数:

void main()

    Tetrimino test(0);

    test.getGrid();


【问题讨论】:

“我不想编辑它” - 如果您想打印私人成员,恐怕您将不得不这样做。我不能说为什么函数是这样写的,但它不能用于外部打印类的成员数组。说了这么多,dataDump 是做什么的? getGrid 可用于打印任何grid。所以这个函数不应该是类的成员。如果此函数仅用于打印内部grid,则根本不需要输入参数gridOut @MikeSeymour dataDump 只是我计划用来打印内部变量以用于我尚未创建的测试目的的函数。我同意即使我不想编辑,我也只能编辑它。对我来说,为什么首先要争论是没有意义的。 “我对如何从 Tetrimino 类中打印出网格数组感到非常困惑和困惑” - 我认为你会更加“卡住”为什么你的成员网格仍然不确定,并且所有那些本地范围的自动grid 声明都无法改变这一点。使用加速警告进行编译应该会显示 7 个不同的“未使用的变量 'grid'”实例或类似的词。 @WhozCraig 是的,我现在在那儿。我更加困惑为什么会这样。我正在努力找出为什么会发生这种情况,但我明白你指出了什么。 【参考方案1】:

正如你提到的,头文件是提供给你的,我猜这是一个任务。 getGrid 方法旨在为外部调用者提供接口以获取 Tetrmino 对象网格的副本。由于不能从函数返回数组,getGrid 方法提供了一个输出参数。

示例用法:

void Tetrimino::getGrid(int gridOut[][TETRIMINO_GRID_SIZE]) 
   for(int i = 0; i < TETRMINO_GRID_SIZE; i++)  
      for(int j = 0; j < TETRMINO_GRID_IZE; j++ )  
          gridOut[i][j] = grid[i][j];
      
   


...
...

Tetrmino obj(3);

... 
... 

int grid[TETRIMINO_GRID_SIZE][TETRMINO_GRID_SIZE];
obj.getGrid(grid);
// now grid holds the copy of interal grid
for(int i = 0; i < TETRMINO_GRID_SIZE; i++)  
   for(int j = 0; j < TETRMINO_GRID_IZE; j++ )  
       std::cout << grid[i][j] << " ";
   
   std::cout << "\n";

std::cout << std::flush;

编辑: 扩展答案:为什么不分配网格?

问题是,在您的构造函数中,您要声明一个与类成员同名的新 int 数组。这意味着,您没有初始化成员变量。 C++ 不允许在初始化后分配给原始数组,你只剩下复制了。

将新变量更改为gridNew 或类似的值,然后从gridNew 逐个复制到grid,就像您现在在getGrid 方法中从grid 复制到gridOut 一样。

【讨论】:

你是正确的,我从哪里得到了标题。所以如果我理解正确的话,在这个解决方案中,getGrid 的公共功能只存在于提取网格信息? getGridgetColor 的方法相同。唯一不同的是,因为使用的是原始数组,所以返回一个副本就没有那么简单了。 啊,我明白了。感谢您的解释!现在,您不会碰巧知道为什么 grid 没有被设置为正确的值吧? 我扩展了答案 非常感谢!真的很棒的解释,你的反应很快!【参考方案2】:

那个方法是完全错误的,它被设计为打印一个参数而不是内部数据,只需删除输入参数并使用内部矩阵。

顺便说一句,您不应该只使用 std::endl 打印 \n,而是直接使用 \n。 std::endl 将刷新 fd 并花费更多时间。

【讨论】:

直接使用\n是什么意思?您能否详细说明我将如何使用 \n 而不是 endl? @Zearia 写std::cout &lt;&lt; ... &lt;&lt; '\n' 而不是std::cout &lt;&lt; ... &lt;&lt; std::endl,除非您绝对希望它立即出现在屏幕上。【参考方案3】:

不要从您的 main 调用您的私人成员,也不要从您的 main 发送任何参数。它是您的成员,您不需要任何打印出来,您只需使用它,如果您对直接使用它感到困惑,请在您的函数中使用 this 关键字

for (int row = 0; row < TETRIMINO_GRID_SIZE; row++)
  
      //goes through each col of current row
      for (int column = 0; column < TETRIMINO_GRID_SIZE; column++)
      
          cout << this->grid[row][column] << " ";
      
      //new line between rows
      cout << endl;
  

【讨论】:

以上是关于c++ 类:在公共函数中使用私有数组?的主要内容,如果未能解决你的问题,请参考以下文章

让公共成员变量访问 C++ 中同一类的私有成员

如何通过函数在 C++ 中设置私有静态数组?

C++ 中具有公共继承的虚函数和私有成员

在 C++ 中的类中初始化与公共和私有相同的函数:它是如何工作的?

c++ 垃圾成员值,同时使用公共和私有重载构造函数

在 C++ 中调用私有方法