使用重载流插入运算符输出对象的双指针成员?
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::vector
或 std::valarray
来存储所有 M*N 值并使用 arr[n*cols+m]
引用元素。让用户简单地预先指定行数和列数,分配足够的内存并用 std::cout >> arr[i*cols+j]
填充它。为输入流和矩阵重载 operator>>
而不是 userInput
函数。
我目前正在实现一个 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::vector
或 std::valarray
来存储所有 M*N 值并使用 arr[n*cols+m]
引用元素。让用户简单地预先指定行数和列数,分配足够的内存并用 std::cout >> arr[i*cols+j]
填充它。为输入流和矩阵重载 operator>>
而不是 userInput
函数。