Вывод двойного указателя на объект с оператором вставки перегруженного потока?

В настоящее время я реализую класс, который может представлять матрицы с использованием динамических массивов с двойными указателями (типа 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 << ": " ;

из моей функции перегрузки вставки потока никогда не печатается на консоль, несмотря на то, что она предназначена для печати для каждой строки, но программа пропускает ее во внутреннюю часть цикла и печатает этот чертов адрес. Я просто не понимаю.

У меня закончились опции (я редактировал / перекомпилировал / запустил и отлаживал в GDB/valgrind в течение последних 5 часов), исчерпал практически все ресурсы, которые я мог найти относящиеся к моей проблеме, и поэтому теперь в 2:45 утра, ужасно лишенный сна, я обращаюсь к вам, храбрым душам ТАК. Любая помощь с благодарностью, спасибо! (Извините, если это бессвязно и трудно понять, я очень устал!)

1

Решение

У вашего оператора потока есть второй формальный параметр const clMatrix *&printMatrix, Это lvalue ссылка на константный указатель на clMatrix, Вы вызываете это с неконстантным указателем lvalue на clMatrix, которая не будет привязана к ссылке (если она есть, вы можете использовать ее для нарушения безопасности const).

В результате единственной доступной перегрузкой является ostream функция-член operator<<(const void* value), который печатает необработанное значение указателя.

Любая из следующих подписей будет работать:

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

Но было бы более идиоматичным взять clMatrix параметр напрямую по константной ссылке:

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

Другие решения

Ваш перегруженный оператор называется? const clMatrix*& кажется странным Из-за этого компилятор выбирает встроенный operator<<, Передайте просто const-ссылку на clMatrix, И называть это cout << *aMatrix, Если вы сделаете это, компилятор не перепутает вашу перегрузку с build-it operator<<,

Ваш код выглядит правильно, но довольно сложно. Я бы использовал один std::vector или же std::valarray хранить все значения M * N и обращаться к элементу, используя arr[n*cols+m], Позвольте пользователю заранее указать количество строк и столбцов, выделить достаточно памяти и заполнить его std::cout >> arr[i*cols+j], перегрузка operator>> для входного потока и вашей матрицы вместо userInput функция.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector