简体   繁体   English

如何读取main.cpp文件中class私有成员中的数据?

[英]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.我尝试在main.cpp文件中读取并记住其中的数据。 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.我使用<fstream>库从文件中读取数据并将它们删除到 output 的ofstream文件中。我使用.h文件和.cpp文件以及main.cpp文件。

Here is code in matrix.h file:这是matrix.h文件中的代码:

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:这是matrix.cpp文件:

#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:主.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.函数SumOfElements()和 Averaged_Matrix( Averaged_Matrix()写在另一个连接的文件中,它们可以正常工作。

Is it possible to use private members without setters and getters?是否可以在没有 setter 和 getter 的情况下使用私有成员?

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.您不允许从包含 class 的外部访问私有字段。但看起来您有一个采用 R 和 C 的构造函数——因此读取这些字段然后构造一个矩阵 object,将 R 和 881037566 作为 81856388 传递

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.因此,您可以添加 getter 和 setter,也可以重新构建您尝试做的事情的方式。

 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.如果您觉得有必要访问 class 的private成员,那么就会出现严重错误。 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.在您的特定情况下, class 设计本身构思不当。 In particular the problem attempted to be masked by declaring certain members private is, that altering them after construction will corrupt the classes behavior.特别是试图通过将某些成员声明为private来掩盖的问题是,在构造后更改它们会破坏类的行为。

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.您对此的处理方法使这是一个XY 问题:您认为您必须以某种方式处理访问说明符,而实际上,不得更改的 class 成员的非常量是您遇到麻烦的原因。

BTW: double **mat;顺便说一句: double **mat; does not make a 2D array.不会制作二维数组。 It makes an (1D) array of pointers to (1D) arrays of doubles.它使一个 (1D) 指针数组指向 (1D) arrays 双精度数。 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.访问时的二级间接访问会降低性能,更不用说矩阵的行/列在 memory 中很可能不连续,因此由于缓存未命中和难以预取而导致性能不佳。

A much better design for you class would look like this对你来说更好的设计 class 看起来像这样

#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.因此,当您觉得需要直接访问 Matrix::mat 的元素时,您可以这样做,而且相对安全。 The compiler will forbid you to alter the编译器会禁止你改变

Now you might wonder why I declared a type for the dimensions that is unsigned short .现在您可能想知道为什么我为维度声明了一个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.这样做的原因是,在大多数相关架构和平台上(8 位和 16 位微控制器除外), short的乘法结果将始终适合size_t ,因此这可以防止在分配 integer 时遇到溢出错误二维数组。

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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