如何在c ++中传递2d数组对象的功能?

时间:2012-09-26 07:38:57

标签: c++ parameter-passing

我有一个二维固定大小的“spot”类对象数组 Spot map [row] [col]; // row& col是动态改变的整数 我想把它传递给一个函数 bool isFilled(int row,int col,Spot [row] [col]){} 如何定义功能?如何删除此数组?请参阅我的代码。谢谢你的帮助。

Spot.h

    #ifndef SPOT_H
#define SPOT_H

class Spot
{
private:
    bool isBunny;
    int nextCycle;
public:
    static const int UP = 0;
    static const int RIGHT = 1;
    static const int DOWN = 2;
    static const int LEFT = 3;
    static const int SLEEP = 4;

    virtual void setSpot(bool newIsBunny);
    Spot();
    ~Spot();
    virtual int getNextCycle();
    virtual void setNextCycle();
    virtual bool getIsBunny();
    virtual void makeBunny();
};

void Spot::setSpot(bool newIsBunny)
{
    isBunny = newIsBunny;
    nextCycle = UP;
}

Spot::Spot()
{
    isBunny = false;
    nextCycle = UP;
}

Spot::~Spot()
{
}

void Spot::setNextCycle()
{
    if (nextCycle != SLEEP)
    {
        nextCycle++;
    }
}

int Spot::getNextCycle()
{
    return nextCycle;
}

bool Spot::getIsBunny()
{
    return isBunny;
}

void Spot::makeBunny()
{
    if (!isBunny)
        nextCycle = UP;
    isBunny = true;
}


#endif  /* SPOT_H */


Bunny.cpp



#include "Spot.h"
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <boost/algorithm/string.hpp>


using namespace std;


static string line;
static ifstream inFile;
static ofstream outFile;
bool isFilled(int x, int y, Spot **myMap);

int main () {
  int numSims = 0;
  inFile.exceptions ( ifstream::failbit | ifstream::badbit );

  try {
    inFile.open ("/home/mike/Desktop/input.txt");
    outFile.open ("/home/mike/Desktop/output.txt");
   // while(!inFile.eof())
      {

         getline (inFile,line);
        numSims= atoi(line.c_str());
       //cout<<"numSims: "<<numSims<<endl;
        for (int i = 0;i < numSims;i++)
            {
                int minPerCycle = 1;
                getline (inFile,line);
                minPerCycle= atoi(line.c_str());

            //cout << "minPerCycle: "<<minPerCycle <<endl;

                int row = 0;
                int col = 0;
                    getline (inFile,line);
                    std::vector<std::string> xy;
                    boost::split(xy, line, boost::is_any_of(" "));
                    row=atoi(xy.at(0).c_str());
                    col=atoi(xy.at(1).c_str());
                    //cout <<"row: "<< row<<endl;
                    //cout << "col: "<<col<<endl;


                    Spot** myMap = new Spot* [col];
                    for(int i = 0; i < col; ++i)
                        myMap[i] = new Spot [row];

                    //std::vector<std::vector<Spot> > myMap(x, std::vector<Spot>(y));
                    for (int i = 0;i < row;i++)
                            {
                                getline (inFile,line);
                                //cout<<line<<endl;
                                for (int j = 0;j < col;j++)
                                {
                                    if (line[j] == 'B')
                                    {
                                        myMap[i][j].setSpot(true);

                                    }
                                    else
                                    {
                                        myMap[i][j].setSpot(false);

                                    }
                                }
                            }
                int numCycles = 1;

                if (isFilled(row,col,myMap))
                {
                    numCycles = 0;
                }

                while (!isFilled(row,col,myMap))
                {
                    numCycles++;

                    for (int j = 0;j < row;j++)
                    {
                        for (int k = 0;k < col;k++)
                        {
                            if (myMap[j][k].getIsBunny())
                            {       //cout<< j<<" "<<k<<" " <<"true"<<endl;
                                    switch (myMap[j][k].getNextCycle())
                                    {
                                        case Spot::UP :
                                            if (j>0)
                                            myMap[j-1][k].makeBunny();
                                            break;
                                        case Spot::RIGHT :
                                            if (k<col-1)
                                            myMap[j][k + 1].makeBunny();
                                            break;
                                        case Spot::DOWN :
                                            if (j<row-1)
                                            myMap[j+ 1][k].makeBunny();
                                            break;
                                        case Spot::LEFT :
                                            if (k>0)
                                            myMap[j][k - 1].makeBunny();
                                            break;
                                    }
                                    myMap[j][k].setNextCycle();
                                }
                            //cout<< j<<" "<<k<<" " <<"outside"<<endl;
                        }
                    }

                }
                int time = numCycles*minPerCycle;
                outFile<<"It took " <<time <<" minutes for the bunnies to take over the world!\n";
                cout<<"It took " <<time <<" minutes for the bunnies to take over the world!\n";
                for(int i=0; i < col; i++) {
                   delete [] myMap[i];
                }
                delete myMap;

            }
      }

       inFile.close();
       outFile.close();

}
  catch (ifstream::failure e) {
    cout << "Exception opening/reading file";
  }

  return 0;
}


bool isFilled(int row, int col,Spot **myMap)
{
    for (int i = 0;i < row;i++)
    {
        for (int j = 0;j < col;j++)
        {
            if (!myMap[i][j].getIsBunny())
            {
                //cout<<"true ";
                return false;

            }
            //else
            //  cout<<"false ";


        }
        //cout<<endl;

    }
    return true;
}

3 个答案:

答案 0 :(得分:0)

必须尝试使用​​指针传递吗?

static bool isFilled(int row, int col,Spot** yourMap)

我不确定编译器是否接受Spot myMap[row][col] row并且col似乎是在运行时设置的。

您可能需要以下列方式分配内存

Spot** myMap = new Spot* [col];
for(int i = 0; i < col; ++i)
    myMap[i] = new Spot [row];

删除内存需要您使用类似的for loop,但请记得致电delete []

答案 1 :(得分:0)

我认为你可以将2D数组的引用发送到你想要使用2D数组的方法中。

bool isFilled(int row, int col, Spot &m){  // if you want a fix position in the array
 // Code
}

如果要删除阵列,则必须使用删除操作符。

首先,您必须删除指针数组指向的所有数组,即

for(int i=0; i < size; i++) {
   delete [] spot[i];  // Depends on what you have called the array
}

然后你必须用

删除指针数组
delete [] spot;   

答案 2 :(得分:0)

  

发现myMap [row] [col];

这不是合法的C ++代码。您可以在C99中执行此操作,但不能在C ++中执行此操作。

您在C ++中有两个基本选择:

  1. 使用您视为二维数组的一维数组。
  2. 使用参差不齐的2D数组而不是连续的2D数组。
  3. 使用一维数组的关键优势在于速度快。如果你需要速度,这是要走的路。图形程序员经常使用这种方法,因为他们需要这种速度。缺点是您必须将2D索引转换为单个索引。例如,map[i][j]可能会变为map[i*col+j](行主要订单)或map[i+j*row](列主要订单)。

    使用不规则数组的主要优点是索引是自然的。缺点是需要管理更多内存,访问速度要慢得多。对于扁平化阵列,访问包括少量整数操作和单个内存查找。衣衫褴褛的数组需要两次内存查找。

    这是C ++,所以我的建议是让你的地图成为一个类。提供一个非默认构造函数,其行和列大小分配内存,析构函数(如果需要)进行清理。如果使用std::vector作为底层存储机制,它将为您进行分配和清理。提供operator()的重载以充当地图的索引机制。现在隐藏了用于表示地图的机制。你可以从矢量向量开始,如果这太慢,切换到扁平数组方法。