Hi *,

I have some doubts about passing parameters to a method of a class. I am not sure if it is a problem of my design of the app or a problem of the implementation, I mean C++ knowledge.

I have a class called MatrixHandler : The idea is to manage a matrix simply-basic

MatrixHandler.h
#ifndef MATRIXHANDLER_H
#define MATRIXHANDLER_H

using namespace std;

class MatrixHandler
{
  private:
    double **data;
  public:
    MatrixHandler() {}
    MatrixHandler(int rows, int cols);
    ~MatrixHandler();
    void setMatrixValue(int row, int col, double value);
    double getMatrixValue(int row, int col);
};
#endif
MatrixHandler.cpp

#include <iostream>

#include "MatrixHandler.h"

MatrixHandler::MatrixHandler(int rows, int cols)
{
  data = new double*[rows];

  for (int i = 0;i<rows;i++)
    data[i] = new double[cols];
}

MatrixHandler::~MatrixHandler()
{
  delete[] data;
}

void MatrixHandler::setMatrixValue(int row, int col, double value)
{
  data[row][col] = value;
}

double MatrixHandler::getMatrixValue(int row, int col)
{
  return data[row][col];
}

And a class called Instance : The idea is to read all .txt files of a directory and take each file and get the data an put it in a matrix which I want to use in my main program

Instance.h
#ifndef INSTANCE_H
#define INSTANCE_H

#include "MatrixHandler.h"

using namespace std;

class Instance
{
  private:
    int n;
    int m;
  public:
    Instance() { }
    vector<string> listFiles(string dir);
    void getNewInstance(string file);
    void setN(int number);
    void setM(int number);
    int getN();
    int getM();
};

#endif
Instance.cpp

#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <vector>
#include <string>
#include <iostream>
#include <istream>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <iomanip>

#include "Instance.h"
#include "MatrixHandler.h"

vector<string> Instance::listFiles(string dir)
{
  vector<string> files = vector<string>();
  DIR *dp;
  struct dirent *dirp;
  string fileName;
  //string npos;

  // check if directory can be opened
  if((dp  = opendir(dir.c_str())) == NULL) {
    cout << "Error(" << errno << ") opening " << dir << endl;
    exit(-1);
  }

  // reading directory until there is no more filed to read
  // this includes . files and hide files such as .swp (VIM temporary
  // files)
  while ((dirp = readdir(dp)) != NULL) {
    fileName = string(dirp->d_name);
    // our interest are txt files only but not the "best_values" txt
    // files
    if ((fileName.substr(fileName.find_last_of(".") + 1) == "txt") && \
                    ((fileName.find("best_values")) == string::npos)) {
      files.push_back(fileName);
    }
  }

  closedir(dp);
  return files;
}

void Instance::getNewInstance(string fileName)
{
  ifstream file(fileName.c_str()); // reading the file

  int from, to;
  double cost;

  if (file.is_open()) // Open file operation succees
  {
    file >> from >> to;
    setN(from);
    setM(to);
    MatrixHandler data(from,from);
    while (file >> from >> to >> cost)
    {
      data.setMatrixValue(from,to,cost);
      data.setMatrixValue(to,from,cost);
    }
    file.close();
  }
  else cout << "File" << fileName << "can not be opened" << endl;

}

void Instance::setN(int number)
{
  n = number;
}

void Instance::setM(int number)
{
  m = number;
}

int Instance::getN()
{
  return n;
}

int Instance::getM()
{
  return m;
}

and of course my main program

MMDP_SA.cpp

#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <vector>
#include <string>
#include <iostream>
#include <iomanip>

#include "Instance.h"
#include "MatrixHandler.h"

using namespace std;

int main()
{
        Instance instances;
        string dir = string(".");
        vector<string> files = vector<string>();
        files = instances.listFiles(dir);
        MatrixHandler ss;
        //for (unsigned int i = 0; i < files.size();i++) 
        for (unsigned int i = 0; i < 1;i++)
        {
          //cout << files[i] << endl;
          instances.getNewInstance(files[i]);
          cout << ss.getMatrixValue(1,2) << endl;
        }
        return 0;
}

I think (IMHO) this:

I designed the matrix class keeping in mind that just its methods can modify (manipulate) the matrix.

So trough matrix class methods the class Instance can set the values in the matrix but I can not figure out the best/correct way to work with the matrix in the main app :

1.- One solution is to instance the class matrix in the main program and pass it to Instance methods to work with it

2.- By other hand is possible to make the getNewInstance method of Instance class type of MatrixHandler.

My point is that I am not sure whic is the best/correct way to solve this doubt.

Does someone drop some ideas?..

Thanks in advanced and best regards.

Well to solve this I just :

1.- I changed line 17 of Instance.h from
This :

void getNewInstance(string file);

To this :

MatrixHandler& getNewInstance(string file);

2.- Add

#include <stdexcept>

to Instance.cpp

3.- Changed the implementation of the method from :
This :

void Instance::getNewInstance(string fileName)
{
  ifstream file(fileName.c_str()); // reading the file
  int from, to;
  double cost;
  
  if (file.is_open()) // Open file operation succees
 {
    file >> from >> to;
    setN(from);
    setM(to);
    MatrixHandler data(from,from);
    
    while (file >> from >> to >> cost)
   {
      data.setMatrixValue(from,to,cost);
     data.setMatrixValue(to,from,cost);
   }
   file.close();
  }
  else cout << "File" << fileName << "can not be opened" << endl;
}

To this :

MatrixHandler& Instance::getNewInstance(string fileName)
{
  ifstream file(fileName.c_str()); // reading the file

  int from, to;
  double cost;

  if (!file.is_open()) // Open file operation succees
  {
    cerr << "File" << fileName << "can not be opened" << endl;
    throw exception();
  }

  file >> from >> to;
  setN(from);
  setM(to);
  MatrixHandler *data = new MatrixHandler(from,from);
  while (file >> from >> to >> cost)
  {
    data->setMatrixValue(from,to,cost);
    data->setMatrixValue(to,from,cost);
  }
  file.close();
  return *data;
}

4.- Delete line 22 of MMDP_SA.cpp

5.- Change line 27 from :
This :

instances.getNewInstance(files[i]);

To this :

MatrixHandler& ss = instances.getNewInstance(files[i]);

The code that I posted before this one returned these errors :
$ make
g++ -Wall -c MMDP_SA.cpp
g++ -Wall -c MatrixHandler.cpp
g++ -Wall -c Instance.cpp
Instance.cpp: In member function ‘MatrixHandler& Instance::getNewInstance(std::string)’:
Instance.cpp:63: warning: reference to local variable ‘data’ returned
Instance.cpp:72: warning: control reaches end of non-void function
g++ -Wall -o mmdp_sa MMDP_SA.o Instance.o MatrixHandler.o

So the first error and solution is explained here See the section called : C++ References as Return Values

And te second one was solved using an exception handler (*so* important).

So I think (IMHO) I solved this thread.

Thanks to those who take a minute to view the code :D.

Cheers!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.