使用重载流插入运算符输出对象的双指针成员?

Outputting double pointer member of an object with overloaded stream insertion operator?

我目前正在实现一个 class,它可以使用带双指针(双精度类型)的动态数组表示矩阵,为 矩阵算术 重载 */-/+ operators & 用于输出矩阵的重载流插入运算符

我的项目要求用户将一系列由空格分隔的输入输入到一个字符串中,字符串中的项数等于列数,字符串输入数等于行数。我已经能够成功地写出我的 class 函数定义,但是当我编译和 运行 我的代码时,一旦程序到达重载的插入运算符调用,它只打印一个内存地址而不是每个无论我尝试多少行或多少列,数组中的值。

我的class定义:

class clMatrix {
  private:
    int rows, cols ;
    double **arr ;
  public:
    clMatrix() ;
    ~clMatrix() ;
    void userInput(char matrixId, int &rowN, int &colN) ;
    friend ostream &operator<<(ostream& os, const clMatrix*&) ;
    friend clMatrix &operator+(const clMatrix&, const clMatrix&) ;
    friend clMatrix &operator-(const clMatrix&, const clMatrix&) ;
    friend clMatrix &operator*(const clMatrix&, const clMatrix&) ;
} ;

我的 class 函数定义(特别是输入和输出,因为我没有测试的算术运算符,因为我没有输出要测试)和 main:

输出函数:

ostream& operator<<(ostream& os, const clMatrix *&printMatrix) {
  for(int i = 0; i < printMatrix->rows; ++i) {
    os << "\nRow " << i+1 << ": " ;
    for(int j = 0; j < printMatrix->cols; ++j) {
      os << printMatrix->arr[i][j] << " " ;
    }
  }
  os << endl ;
  return os ;
}

输入函数:

void clMatrix::userInput(char matrixId, int &rowN, int &colN) {
  string in ;
  int idx, rowLen, colLen ;
  double rowarr[50] ;
  bool firstRow = 1 ;
  colLen = 0 ;
  rowLen = 0 ;
  idx = 0 ;
  cout << "Matrix: " << "'" << matrixId << "'" << endl ;
  cout << "Enter row 1: " ;
  getline(cin,in) ;
  while(in != "") {
    ++rowLen ;
    stringstream iss(initial) ;
    while(iss >> rowarr[idx]) {
      ++idx ;
    }
    if(firstRow) {
      colLen = idx ;
      firstRow = 0 ;
    }
    cout << "Enter row " << rowLen + 1 << ": " ;
    getline(cin,in) ;
  }
  idx = 0 ;
  rows = rowLen ;
  cols = colLen ;

  arr  = new double*[rows] ;
  for(int i = 0; i < rows; ++i) {
    arr[i] = new double[cols] ;
  }
  idx = 0 ;
  for(int i = 0; i < rows; ++i) {
    for(int j = 0; j < cols; ++j) {
      arr[i][j] = rowarr[idx] ;
      ++idx ;
    }
  }
}

主要功能:

#ifndef HEADER_H
#define HEADER_H
#include "header.h"
int main() {
  clMatrix *aMatrix ;
  clMatrix *bMatrix ;
  aMatrix = new clMatrix ;
  bMatrix = new clMatrix ;
  char matrixId ;
  int rowsA, rowsB, colsA, colsB ;

  matrixId = 'A' ;
  cout << "Matrix A input:\n" ;
  aMatrix->userInput(matrixId,rowsA,colsA) ;

  matrixId = 'B' ;
  cout << "Matrix B input:\n" ;
  bMatrix->userInput(matrixId,rowsB,colsB) ;

  cout << "Matrix A output:\n" ;
  cout << aMatrix ;
  cout << "Matrix B output:\n" ;
  cout << bMatrix ;

  delete aMatrix ;
  delete bMatrix ;
  return 0 ;
}

当我 运行 程序时,我为每个矩阵获得一个单一的堆分配地址,我认为它们相差 32 位? (我最近的 运行:0x1dbcc20 和 0x1dbcc40)。这是否意味着只有我的两个整数成员变量被分配为每个 16 位?如果是这样,是不是我的内存分配不当?我还尝试了取消引用双精度类型双指针的几乎所有可能的等级,但无济于事。另外,奇怪的是:

os << "\nRow " << i+1 << ": " ;

从我的流插入重载函数中,尽管它打算为每一行打印,但它从不打印到控制台,但程序跳过它进入内部 for 循环并打印那个该死的地址。简直看不懂。

我 运行 没有选择(已经 editing/recompiling/running 并在 GDB/valgrind 中调试了最后 5 个小时),几乎用尽了我能找到的与我的相关的所有资源问题,所以现在在 2:45 上午,睡眠严重不足的我求助于你们,SO 的勇敢灵魂。非常感谢任何帮助,谢谢! (很抱歉,如果这不连贯且难以理解,我很累!)

您的流出运算符有第二个形参 const clMatrix *&printMatrix。这是指向 clMatrix 的 const 指针的左值引用。您使用指向 clMatrix 的左值非常量指针调用它,它不会绑定到引用(如果绑定了,您可以使用它来违反 const 安全)。

因此,唯一可用的重载是 ostream 成员函数 operator<<(const void* value),它打印原始指针值。

以下任一签名都可以使用:

operator<<(ostream&, const clMatrix*const &)
operator<<(ostream&, const clMatrix*)

不过直接用const引用取clMatrix参数会比较地道:

operator<<(ostream&, const clMatrix&)

你的重载运算符被调用了吗? const clMatrix*& 看起来很奇怪。因此,编译器选择内置 operator<<。简单地将 const-reference 传递给 clMatrix。并将其命名为 cout << *aMatrix。如果你这样做,编译器将不会混淆你的重载和 build-it operator<<.

您的代码看起来正确但相当复杂。我会使用单个 std::vectorstd::valarray 来存储所有 M*N 值并使用 arr[n*cols+m] 引用元素。让用户简单地预先指定行数和列数,分配足够的内存并用 std::cout >> arr[i*cols+j] 填充它。为输入流和矩阵重载 operator>> 而不是 userInput 函数。