简体   繁体   中英

How to read data in private members of the class in main.cpp file?

I have a trouble with usage of private members of the class! I try to read and remember data into them in main.cpp file. I don't need to create any other values to remember read data. How to fix this problem and use them? I use <fstream> library to read data from file and remove them into ofstream file for output. I use .h files and .cpp files and main.cpp file.

Here is code in matrix.h file:

class Matrix
{
   private:
      int R; // amount of rows 
      int C; // amount of columns 
      double **mat; // pointer to two-dimensional array
   public:
       Matrix(); // default constructor
       Matrix(Matrix &&) // move constructor 
       Matrix(int, int); // constructor with two parameters 
       double &ReturnReferenceToElement(int, int); // method to return reference to element of array
}

This is matrix.cpp file:

#include <iostream>
#include "matrix.h"

Matrix::Matrix()
{
   R = 3;
   C = 3;
   mat = new double *[R];
   for(int i = 0; i < R; i++)
   {
      mat[i] = new double [C]; 
   }
}

Matrix::Matrix(Matrix &&M)
{
   R = M.R;
   C = M.C;
   for(int i = 0; i < R; i++)
   {
      for(int j = 0; j < C; j++)
      {
         mat[i][j] = M.mat[i][j];
      }
   }
}

main.cpp:

#include <iostream>
#include <fstream>
#include "matrix.h"
using namespace std;

int main()
{
   Matrix m;
   ifstream in("in.txt");
   ofstream out("out.txt");
   in >> R >> C; // here I try to read data from file into private member

   for(int k = 0; k < R; k++)
   {
      for(int s = 0; s < R; s++)
      {
         in >> mat[k][s]; // here I try to read into the private member
      }
   }
   out << SumOfElements(**mat, R, C);
   out << Averaged_Matrix(**mat, R, C);
   return 0;
}

Functions SumOfElements() and Averaged_Matrix() are written in another file which is connected, and they work correctly.

Is it possible to use private members without setters and getters?

You're not allowed to access private fields from outside the containing class. But it looks like you have a constructor that takes R and C -- so read those fields then construct a Matrix object, passing R and C as arguments.

The idea of private methods is that you very specifically aren't supposed to touch them. So you can either add getters and setters, or you can reframe how you're trying to do what you're trying to do.

 int r, c;
 cin >> r >> c;
 Matrix m(r, c);

If you ever feel the need to access private members of a class, then there's something terribly wrong. Either with the classes design, or in the way you want to interact with it.

In your particular case, the class design itself is ill conceived. In particular the problem attempted to be masked by declaring certain members private is, that altering them after construction will corrupt the classes behavior.

Your approach to this makes this is a XY problem : You think that you have to somehow deal with the access specifier, when in fact, the non-constness of members of the class that must not be altered is the cause of your troubles.

BTW: double **mat; does not make a 2D array. It makes an (1D) array of pointers to (1D) arrays of doubles. The two level indirection upon access will kill performance, not to speak of the high likelyhod that rows/columns of the matrix won't be contiguous in memory and thus will perform poorly due to cache misses and it being hard to prefetch.

A much better design for you class would look like this

#include <cstddef>
#include <cmath>
class Matrix
{
public:
    typedef unsigned short dim_t;
    dim_t const R; // amount of rows 
    dim_t const C; // amount of columns 
    double *const mat; // pointer to two-dimensional array

    // NO DEFAULT CONSTRUCTOR!

    // copy constructor 
    Matrix(Matrix const &m)
        : R(m.R), C(m.R)
        , mat(new double[(size_t)R * (size_t)C])
    {
        auto const N = (size_t)R * (size_t)C;
        for(size_t i = 0; i < N; ++i){ mat[i] = m.mat[i]; }
    }

    // constructor with two parameters
    Matrix(dim_t const r_, dim_t const c_)
        : R(r_), C(c_)
        , mat(new double[(size_t)R * (size_t)C])
    {
        auto const N = (size_t)R * (size_t)C;
        for(size_t i = 0; i < N; ++i){ mat[i] = NAN; }
    }

    ~Matrix(){ delete[] mat; }

    // methods to return reference to element of
    // !!! THOSE DO NOT PERFORM BOUNDS CHECKS!
    double &operator()(dim_t const r, dim_t const c)
        { return mat[(size_t)R*(size_t)c + (size_t)r]; }

    double const &operator()(dim_t const r, dim_t const c) const
        { return mat[(size_t)R*(size_t)c + (size_t)r]; }
};

Why is this better? First and foremost, by being declared const members of the struct, the need to "hide" them from the outside, that is protecting them from unintended alteration is gone; if one really want to be so hard pressed to alter those elements it can be done by forcing the compiler into undefined behavior, but the same methods would also allow to discard the access specifiers.

Thus where you feel the need to directly access elements of Matrix::mat you can do so, in relative safety. The compiler will forbid you to alter the

Now you might wonder why I declared a type for the dimensions that is unsigned short . The reason for this is, that on most relevant architectures and platforms out there (except 8 and 16 bit microcontrollers), the result of multiplication of the short will always fit into a size_t , so this prevents running into an integer overflow bug on allocation of the 2D array.

You can then use that like this:

#include <iostream>
#include <fstream>
#include "matrix.h"
int main()
{
    std::ifstream in("in.txt");
    Matrix::dim_t R, C;
    in >> R >> C;
    Matrix m(R,C);

    for( Matrix::dim_t k = 0; k < m.R; k++ )
    for( Matrix::dim_t s = 0; s < m.C; s++ ){
        in >> m(k, s);
    }

    std::ofstream out("out.txt");
    out << SumOfElements(m.mat, m.R, m.C);
    out << Averaged_Matrix(m.mat, m.R, m.C);
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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