我尝试在空闲时间学习C ++基础并遵循书的练习。首先,当我输入9作为行,8作为列时,我得到malloc释放错误。其次,我得到0作为输出,我无法看到我输入的内容。我想写这个程序,因为我可以强化三个规则。这当然不是功课。此外,我认为这是一个难题和有效的问题。如果问题可以回答,那将会很有帮助。因为我在google上搜索过,所以我找不到解决方案的中途问题。另外,你可以检查我的拷贝构造函数,赋值运算符和析构函数,并告诉我我的错误在哪里吗?
编写一个实现二维动态数组的类TwoD 在其构造函数中使用此显示的想法的双打。您 应该有一个指向double的类型指针的私有成员指向 动态数组,以及两个int(或unsigned int)值 MaxRows和MaxCols。您应该为其提供默认构造函数 您将选择默认的最大行和列大小和a 参数化构造函数,允许程序员设置最大值 行和列大小。此外,您应该提供无效成员 允许设置特定行和列条目的函数和a 成员函数,返回特定的行和列条目作为 double类型的值。备注:很难或不可能(取决于 在细节上)重载[]所以它可以按你的意愿工作 二维数组。所以只需使用accessor和mutator函数 使用普通函数表示法。将+运算符重载为朋友 函数添加两个二维数组。这个功能应该 返回其第i行,第j列元素为其总和的TwoD对象 左侧操作数TwoD对象的第i行,第j列元素 和右手操作数TwoD的第i行,第j列元素 宾语。提供一个拷贝构造函数,一个重载的operator =和a 析构函数。声明不更改数据的类成员函数 作为const成员。
我的努力
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
class TwoD
{
public:
TwoD();
TwoD(int row, int column);
void setRowCol();
double getVal(int row, int column);
friend const TwoD operator +(const TwoD& first, const TwoD& second);
int getterRow() const;
int getterCol() const;
void setterRow(int row);
void setterCol(int column);
TwoD(const TwoD& object);
TwoD& operator =(const TwoD& rightSide);
void putArr() const;
~TwoD();
static TwoD constructFromUserInput();
private:
int MaxRows;
int MaxCols;
double **arr;
};
int main(int argc, char const *argv[])
{
cout << "All size of TwoD object must be same\n\n";
TwoD arr1 = TwoD::constructFromUserInput();
TwoD arr2 = TwoD::constructFromUserInput();
TwoD arr3;
arr3 = arr1 + arr2;
TwoD arr4(arr3);
arr1.putArr();
arr2.putArr();
arr3.putArr();
arr4.putArr();
return 0;
}
void TwoD::setRowCol()
{
int r_user;
int c_user;
cout << "Enter num of rows => ";
cin >> r_user;
cout << "Enter num of columns => ";
cin >> c_user;
MaxRows = r_user;
MaxCols = c_user;
TwoD(MaxRows,MaxCols);
}
TwoD::TwoD(int row, int column)
: MaxRows(row), MaxCols(column)
{
arr = new double*[row];
for (int i = 0; i < row; i++)
{
arr[i] = new double[column];
}
for (int i = 0; i < MaxRows; i++)
{
for (int j = 0; j < MaxCols; j++)
{
cout << "Enter for " << i << j << "=> ";
cin >> arr[i][j];
}
}
}
TwoD::TwoD()
: MaxRows(2), MaxCols(2)
{
arr = new double*[2];
for (int i = 0; i < 2; i++)
{
arr[i] = new double[2];
}
}
double TwoD::getVal(int row, int column)
{
return arr[row][column];
}
const TwoD operator +(const TwoD& first, const TwoD& second)
{
TwoD sum;
for (int i = 0; i < first.MaxRows; i++)
{
for (int j = 0; j < first.MaxCols; j++)
{
sum.arr[i][j] = first.arr[i][j] + second.arr[i][j];
}
}
return sum;
}
TwoD::TwoD(const TwoD& object)
{
MaxRows = object.MaxRows;
MaxCols = object.MaxCols;
arr = new double*[MaxRows];
for (int i = 0; i < MaxRows; i++)
{
arr[i] = new double[MaxCols];
}
for ( int i = 0; i < MaxRows; i++ )
{
for ( int j = 0; j < MaxCols; j++ )
{
arr[i][j] = object.arr[i][j];
}
}
}
TwoD::~TwoD()
{
for (int i = 0; i < MaxRows; i++)
delete [] arr[i];
delete [] arr;
}
TwoD& TwoD::operator =(const TwoD& rightSide)
{
if (this == &rightSide)
{
return *this;
}
for (int i = 0; i < MaxRows; i++)
delete [] arr[i];
delete [] arr;
arr = new double*[rightSide.MaxRows];
for (int i = 0; i < rightSide.MaxRows; i++)
{
arr[i] = new double[rightSide.MaxCols];
}
MaxRows = rightSide.MaxRows;
MaxCols = rightSide.MaxCols;
for (int i = 0; i < MaxRows; i++)
{
for (int j = 0; j < MaxCols; j++)
{
arr[i][j] = rightSide.arr[i][j];
}
}
return *this;
}
void TwoD::putArr() const
{
for (int i = 0; i < MaxRows; i++)
{
for (int j = 0; j < MaxCols; j++)
{
cout << arr[i][j] << " ";
}
cout << endl;
}
}
int TwoD::getterRow() const
{
return MaxRows;
}
int TwoD::getterCol() const
{
return MaxCols;
}
void TwoD::setterRow(int row)
{
MaxRows = row;
}
void TwoD::setterCol(int column)
{
MaxCols = column;
}
TwoD TwoD::constructFromUserInput()
{
int r_user;
int c_user;
cout << "Enter num of rows => ";
cin >> r_user;
cout << "Enter num of columns => ";
cin >> c_user;
// Construct an object.
TwoD obj(r_user, c_user);
// Return the object
return obj;
}
答案 0 :(得分:2)
您的复制构造函数创建数组,但从不复制内容。
复制赋值运算符正确执行此操作。就此而言,您有大量重复的new[]
循环,几个delete[]
循环,并且您应该有两个复制循环。将这些因素归结为函数,您只需要将它们弄清楚一次。
sum
创建一个默认大小的对象,然后可能会超出行和列维度。通常(简单和正确)的实现是创建左侧参数的本地副本(使用您在上面修复的副本)并转发到operator+=
。该运营商更容易做对。
你有办法打印出这些矩阵。做吧!到处都做!这样可以很容易地看出哪个阶段出现了问题。
这本书听起来不太好。它没有明显的原因教授不良练习(操作员+技巧是标准的,如果你不能使用unique_ptr
等等,你应该使用vector
。)
编辑:我在这里回复一些评论,因为他们有进入聊天会话的危险,而且我不想花更多的时间在这上面。
我有固定的复制构造函数是不是正确?
现在是了解如何测试和调试代码的好时机。添加打印语句,使用调试器,将内容拆分为可以测试的函数,然后为它们编写测试。
你的意思是几个
delete[]
循环并有两个复制循环
在代码中查找循环。我可以看到3个循环调用new[]
,所有这些循环都基本相同。我可以看到2个循环调用delete[]
,一个在析构函数中,一个在复制赋值运算符中。只需搜索您自己的代码即可获得for
关键字!
我真的找不到打印矩阵的方法
那么TwoD::putArr
来自哪里?不可否认,ostream& operator<<(ostream&, TwoD const &)
将是更好的名称,但是你写了它以便你也可以使用它。
我无法将析构函数导入main()
当主要完成时,您无法停止被调用的析构函数 - 您的对象将超出范围。只需在析构函数中粘贴断点即可调用它。
因为arr是私有的,我该如何测试?
你仍然可以在调试器中看到它,你仍然可以打印内容(如上所述),你仍然可以从单元测试中调用getVal
,你可以直接调用public
直到你# 39;我们已经找到了你的问题
答案 1 :(得分:0)
您的代码出现问题:
void TwoD::setRowCol()
{
int r_user;
int c_user;
cout << "Enter num of rows => ";
cin >> r_user;
cout << "Enter num of columns => ";
cin >> c_user;
MaxRows = r_user;
MaxCols = c_user;
///
/// This constructs a new TwoD object but does not change
/// object on which the function was invoked.
///
TwoD(MaxRows,MaxCols);
}
解决问题的方法:
更新会员资料
void TwoD::setRowCol()
{
int r_user;
int c_user;
cout << "Enter num of rows => ";
cin >> r_user;
cout << "Enter num of columns => ";
cin >> c_user;
// Delete the current memory
for (int i = 0; i < MaxRows; i++)
{
delete [] arr[i];
}
delete [] arr;
MaxRows = r_user;
MaxCols = c_user;
// Allocate new memory.
arr = new double*[MaxRows];
for (int i = 0; i < MaxRows; i++)
{
arr[i] = new double[MaxCols];
}
// Now read the data.
for (int i = 0; i < MaxRows; i++)
{
for (int j = 0; j < MaxCols; j++)
{
cout << "Enter for " << i << j << "=> ";
cin >> arr[i][j];
}
}
}
创建一个返回全新对象的函数
我推荐这种方法。
首先,更新获取行和列的构造函数,使其没有任何代码从用户输入读取数据。
TwoD::TwoD(int row, int column)
: MaxRows(row), MaxCols(column)
{
arr = new double*[row];
for (int i = 0; i < row; i++)
{
arr[i] = new double[column];
}
}
其次,添加static
成员函数以从用户输入构造对象。
static TwoD constructFromUserInput();
并将其实施为:
TwoD TwoD::constructFromUserInput()
{
int r_user;
int c_user;
cout << "Enter num of rows => ";
cin >> r_user;
cout << "Enter num of columns => ";
cin >> c_user;
// Construct an object.
TwoD obj(r_user, c_user);
// Now read the data.
for (int i = 0; i < r_user; i++)
{
for (int j = 0; j < c_user; j++)
{
cout << "Enter for " << i << j << "=> ";
cin >> obj.arr[i][j];
}
}
// Return the object
return obj;
}
第三,使用main
中的新功能。
int main(int argc, char const *argv[])
{
cout << "All size of TwoD object must be same\n\n";
TwoD arr1 = TwoD::constructFromUserInput();
TwoD arr2 = TwoD::constructFromUserInput();
TwoD arr3;
arr3 = arr1 + arr2;
arr1.putArr();
arr2.putArr();
arr3.putArr();
return 0;
}