Questions regarding overloading ostream operator in C++

Questions regarding overloading ostream operator in C++

Bild des Benutzers Eduardo J. Sanchez P.

Dear all,

Context: I am developing a C++ API implementing Mimetic Finite Differences. An important class I am developing is the staggered grid representing my discrete domain:

I am starting simple: one spatial dimension.

For that I have created the MTK's Logically Rectangular One-Dimensional Uniform Staggered Grid class, or MTK_LR1DUniStgGrd.

Issue: I want to overload the ostream operator (<<) so that I can intuitively print the spatial values defining my grid.

Here's my header file:

class MTK_LR1DUniStgGrd: public MTK_LR1DUniGrd {
  friend ostream &operator<<(ostream &, const MTK_LR1DUniStgGrd &);
  public:
    MTK_LR1DUniStgGrd();
    MTK_LR1DUniStgGrd(MTK_Real, MTK_Real, int);
    virtual ~MTK_LR1DUniStgGrd();
    void prt_array();
    
  private:
    MTK_Node *values_;  //!< Collection of nodes.
    int num_cells_;     //!< Number of cell centers.
};

And this is the implementation in the source file:

// An overloaded stream insertion operator cannot be a member function if we
// would like to invoke it with cout, e.g., cout << grid;
ostream& operator<<(ostream& output, const MTK_LR1DUniStgGrd& grid) {
  //! Variables: 1
  int ii; // Iterator.
  //! MTK Classes:
  MTK_Real aux_west_boundary;
  MTK_Real aux_east_boundary;
  MTK_Real aux_nodal_step_size;
  MTK_Real aux_value_sub_ii;
  //! Begin.
  //! Validation stage:
  if (grid.values_ == NULL) {
    cerr << "Staggered grid can not be printed at " <<  __LINE__ - 1 << endl;
    cerr << " of file " << __FILE__ << endl << flush;
    cerr << "MTK: Terminating execution..." << endl << flush;
    exit(EXIT_FAILURE);
  }
  //! Initialization stage:
  aux_west_boundary = MTK_LR1DGrd::west_boundary_node();
  aux_east_boundary = MTK_LR1DGrd::east_boundary_node();
  aux_nodal_step_size = MTK_LR1DUniGrd::nodal_step_size();
  output << "Staggered [a:h:b] = [" << aux_west_boundary << ":" <<
    aux_nodal_step_size<< ":" << aux_east_boundary << "] = " << endl << endl;
  for (ii = 0; ii < (1 + grid.num_cells_ + 1); ii++) {
    aux_value_sub_ii = (grid.values_[ii]).value();
    output << setw(10) << aux_value_sub_ii << " ";
  }
  output << endl;
  return output;
}

However, when building, I am getting the following output:

icpc    -c -g -Iinclude -MMD -MP -MF build/Debug/Intel-Linux-x86/src/mtk_lr_1d_uni_stg_grd.o.d -o build/Debug/Intel-Linux-x86/src/mtk_lr_1d_uni_stg_grd.o src/mtk_lr_1d_uni_stg_grd.cc
src/mtk_lr_1d_uni_stg_grd.cc(73): error #308: member "mtk::MTK_LR1DUniStgGrd::values_" (declared at line 76 of "include/mtk_lr_1d_uni_stg_grd.h") is inaccessible
    if (grid.values_ == NULL) {
             ^
src/mtk_lr_1d_uni_stg_grd.cc(81): error: a nonstatic member reference must be relative to a specific object
    aux_west_boundary = MTK_LR1DGrd::west_boundary_node();
                        ^
src/mtk_lr_1d_uni_stg_grd.cc(82): error: a nonstatic member reference must be relative to a specific object
    aux_east_boundary = MTK_LR1DGrd::east_boundary_node();
                        ^
src/mtk_lr_1d_uni_stg_grd.cc(83): error: a nonstatic member reference must be relative to a specific object
    aux_nodal_step_size = MTK_LR1DUniGrd::nodal_step_size();
                          ^
src/mtk_lr_1d_uni_stg_grd.cc(87): error #308: member "mtk::MTK_LR1DUniStgGrd::num_cells_" (declared at line 77 of "include/mtk_lr_1d_uni_stg_grd.h") is inaccessible
    for (ii = 0; ii < (1 + grid.num_cells_ + 1); ii++) {
                                ^
src/mtk_lr_1d_uni_stg_grd.cc(88): error #308: member "mtk::MTK_LR1DUniStgGrd::values_" (declared at line 76 of "include/mtk_lr_1d_uni_stg_grd.h") is inaccessible
      aux_value_sub_ii = (grid.values_[ii]).value();
                               ^
compilation aborted for src/mtk_lr_1d_uni_stg_grd.cc (code 2)

As it can be seen, there are two kinds of problems that I am getting:

  1. Those related to the fact that the private members of the grid cannot be accessed, and
  2. Those related to invoking the base class to extract the values that I need, which I do not understand, since I have a public method called prt_array, which uses this code, and works.

Any hints?

Thanks in advanced! :D

Eduardo J. Sanchez P.
5 Beiträge / 0 neu
Letzter Beitrag
Nähere Informationen zur Compiler-Optimierung finden Sie in unserem Optimierungshinweis.

>>...
>>aux_west_boundary = MTK_LR1DGrd::west_boundary_node();
>>

I don't think that the assignment is possible without a C++ assignment operator or a copy non-default constructor of the MTK_Real class.

Bild des Benutzers Eduardo J. Sanchez P.

Quote:

Sergey Kostrov wrote:

I don't think that the assignment is possible without a C++ assignment operator or a copy non-default constructor of the MTK_Real class.

Yes it can be done... you doubt arises from a naming problem, which I have solved.

Thanks.

Eduardo J. Sanchez P.
Bild des Benutzers Eduardo J. Sanchez P.

Dear Sergey,

Yes it does. However, your doubt arises from a naming issue, which I have fixed.

Thanks.

Eduardo J. Sanchez P.
Bild des Benutzers Eduardo J. Sanchez P.

In fact, I have solved this problem:

ostream& mtk::operator<<(ostream& output, const MTK_LR1DUniStgGrd& grid)

I specified that the global definition was within the scope of the mtk namespace.

Thanks.

If I could, I would flag this thread as solved.

 

Eduardo J. Sanchez P.

Melden Sie sich an, um einen Kommentar zu hinterlassen.