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

时间:2016-04-12 09:55:03

标签: c++ arrays oop matrix double-pointer

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

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

我的班级定义:

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

我的类函数定义(特别是输入和输出,因为我没有测试过算术运算符,因为我没有测试输出)和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 << ": " ;
从我的流插入重载函数

永远不会打印到控制台,尽管它打算为每一行打印,但程序跳过它进入内部循环并打印一个frickin'地址。我根本就不明白。

我已经用完了选项(过去5个小时内一直在GDB/valgrind编辑/重新编译/运行和调试),几乎找不到我能找到的与我的问题相关的所有资源,所以现在在凌晨2点45分,严重的睡眠剥夺了我转向你,勇敢的灵魂。非常感谢任何帮助,谢谢! (很抱歉,如果这种语法不连贯,很难理解,我很累!)

2 个答案:

答案 0 :(得分:1)

您的流出运算符具有第二个正式参数const clMatrix *&printMatrix。这是对clMatrix的const指针的左值引用。你用一个引用clMatrix的左值非const指针来调用它,它不会绑定到引用(如果有的话,你可以使用它来违反const安全性)。

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

以下任何一种签名都有效:

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

但是通过const引用直接获取clMatrix参数会更加惯用:

operator<<(ostream&, const clMatrix&)

答案 1 :(得分:0)

您的重载运算符是否被调用? <ul *ngFor="#item of items"> <li>Item: {{item.itemKey}}</li> </ul> //Load items simulating remote load setTimeout(function(){ for (let i = 0; i < 1500; i++) { self.items.push(new Item(i+"")); } },1000); 似乎很怪异。因此,编译器选择内置const clMatrix*&。简单地将const-reference传递给operator<<。并称之为clMatrix。如果这样做,编译器不会将重载与build-it cout << *aMatrix混淆。

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