昨天我的班级进行了实验室考试,在那里我们必须制作一个矩阵类并重载operation+()
。在我去单元测试之前,我认为我的方法是正确的...我知道这是很多文字;但是,我花了实验室的其余部分试图弄清楚出了什么问题,并且无法弄清楚为什么临时对象矩阵在赋值操作符调用之前超出了范围。
代码如下:
矩阵标头
#include <iostream>
#include <iomanip>
using namespace std;
class Matrix
{
Public:
// Constructor and Destructor Suite
Matrix(int x, int y); // Lab TA stated that Matricies would never go above two dimensions
~Matrix();
// Access and Mutation
void set(int row, int column, int value); // This function sets the value of a given matrix coordinate at row, column to value
int get(int row, int column) const; // This function returns the value of a matrix at row, column
Matrix& operator=(const Matrix& Q)
{
cout << "Called Assignment" << endl;
int r, c;
r = Q.rows; c = Q.columns;
for (int i = 0; i < r; i++)
{
for (int k = 0; k < c; k++)
{
cout << "Address of Calling Objet pointer Int: " << this->pMatrixOfInt[i][k] << setw(5) << *this->pMatrixOfInt[i][k] << endl;
cout << "Address of Reference Object: " << Q.pMatrixOfInt[i][k] << setw(5) << *Q.pMatrixOfInt[i][k] << endl;
*(this->pMatrixOfInt[i][k]) = *(Q.pMatrixOfInt[i][k]);
}
}
return *this;
}
const Matrix operator+(const Matrix& Q);
friend ostream& operator<<(ostream& output, const Matrix& Q);
friend istream& operator>>(istream& input, Matrix& Q);
private:
int rows, columns;
int* pMatrixOfInt[50][50]; // Specification document said that these values would never go above 50
};
Matrix.cpp
/*
Matrix Class Definition
14 March 2014
*/
#include <iomanip>
#include <iostream>
#include "Matrix.h"
// Constructor
Matrix::Matrix(int x, int y)
{
cout << "Constructor Called" << endl;
this->rows=x;
this->columns=y;
for (int i=rows-1; i>=0; i--) // If X and Y are both 50 then the starting value
{ // for i and k should be 49 because of how arrays
for (int k=columns-1; k>=0; k--) // are indexed. Hence the rows-1
{
pMatrixOfInt[i][k] = new int;
}
}
}
// Destructor
Matrix::~Matrix()
{
cout << "Destructor Called" << endl;
for (int i=rows-1; i>=0; i--) // If X and Y are both 50 then the starting value
{ // for i and k should be 49 because of how arrays
for (int k=columns-1; k>=0; k--) // are indexed. Hence the rows-1
{
delete pMatrixOfInt[i][k];
}
}
}
// Access and Mutation
void Matrix::set(int row, int column, int value)
{
*pMatrixOfInt[row][column] = value;
}
int Matrix::get(int row, int column) const
{
return *pMatrixOfInt[row][column];
}
// Overloaded Addition Operator (Possible Scope Problem)
const Matrix Matrix::operator+(const Matrix& Q)
{
cout << "Addition Operator Called" << endl;
int rows, columns;
rows = Q.rows;
columns = Q.columns;
Matrix newMatrix(rows, columns);
cout << "newMatrix Rows: " << newMatrix.rows << " -- newMatrix columns: " << newMatrix.columns << endl; // Make a new matrix. Constructor will initialize the pointer Matrix
int newValue;
for (int i=0; i<rows; i++)
{
for (int k=0; k<columns; k++)
{
newValue = this->get(i,k);
newValue += Q.get(i,k);
newMatrix.set(i,k, newValue);
cout << setw(5) << newMatrix.get(i, k);
}
cout << "\n";
}
return newMatrix;
}
// Friend definitions for i/ostreams.
ostream&::operator<<(ostream& output, const Matrix& Q)
{
for (int r = 0; r<Q.rows; r++)
{
for (int c = 0; c<Q.columns; c++) // hahaha
{
output << setw(4) << Q.get(r,c);
}
output << "\n";
}
return output;
}
istream&::operator>>(istream& input, Matrix& Q)
{
int value;
for (int r = 0; r<Q.rows; r++)
{
for (int c = 0; c<Q.columns; c++)
{
input >> value;
Q.set(r,c,value);
}
}
return input;
}
当我尝试做这样的事情时:
newMatrix = oldMatrixA + oldMatrixB;
cout << newMatrix;
我收到了以下一系列输出,然后是BLOCK_HEADER_ERROR:
Addition Operator Called
0 1 2 3
1 3 5 7
Destructor Called
Assignment Called
Lots of output here regarding address of calling object and value along with the reference object and value of that too
!!!BLOCK_HEADER_ERROR!!!
任何人都可以告诉我为什么加法运算符返回的临时对象在赋值运算符之前超出范围,即使它们位于同一行并且newMatrix是返回对象,因此直到调用它的范围要求销毁它?
提前感谢您的帮助,我昨晚睡不好觉,因为TA让我上班,我知道这些工作已被窃听,我无法弄清楚问题。
我知道这是很多代码,这是我向StackOverflow发布的最长的问题;但是,我喜欢睡得好,直到我知道出了什么问题,我才认为我会休息得很好。
答案 0 :(得分:1)
为什么使用指针存储值?改为使用普通整数,你没事。
首先考虑过早的&#34;破坏:
在您的代码中,您实际上有两个临时值(如果没有返回值优化):
第一个是newValue
,第二个是operator+
返回的右值临时值。
在newValue
复制到临时右值后,newValue
被破坏(您看到的消息)。
第二个问题是:您没有指定自定义复制构造函数(想想rule of three)。因此,rvalue临时副本具有指向解除newValue
时释放的整数的所有指针。
如果你不能使用普通整数,那么你必须编写你真正复制的复制构造函数(为新矩阵分配新的整数)。
如果你可以使用普通整数,那么使用它们一切都很好(不需要自定义析构函数/复制构造函数/复制赋值运算符)
示例复制构造函数:
Matrix::Matrix(const Matrix &other) {
this->rows=other.rows;
this->columns=other.columns;
for (int row = 0; row < rows; ++row) {
for (int column = 0; column < columns; ++column) {
// allocate a new integer with the value
// copied from the other matrix
pMatrixOfInt[row][column] = new int(*other.pMatrixOfInt[row][column]);
}
}
}