【发布时间】:2022-01-09 22:51:48
【问题描述】:
我正在编写 Matrix 类并且到了需要创建 Array 对象数组的地步,但是 Array 不能有没有参数的构造函数(它需要 m 参数来为其分配内存)。我搜索并没有找到解决方案,人们只建议用 Vector 对象来做,但我不能用数组以外的任何东西来做。然后一个朋友给我发了适合他们的矩阵构造函数,但即使他们也不知道它为什么会起作用。
Matrix::Matrix(int n, int m):n(n),m(m) {
srand(time(0));
this->data=new Array(n);
for(int i=0; i<n; i++){
this->data[i].m=this->m;
this->data[i].data=new int[m];
for(int j=0; j<this->m; j++){
this->data[i].data[j]= rand()%10;
}
}
}
我不明白这个this->data[i] 是如何定义的? [] 运算符不会在任何地方重载,并且数据只是单个 Array 对象而不是 Array-s 的数组。那么为什么以及如何工作而不是编译错误呢?
源文件:
标题:
#define ROK04_ROK04_H
class Array{
protected:
int* data;
int m;
public:
Array(int m);
Array& operator = (const Array& a);
virtual ~Array();
Array& operator+=(const Array& a);
virtual void setElem(int pos, int value);
virtual void print() const;
friend class Matrix;
};
class Matrix{
protected:
Array* data;
int n;
int m;
public:
Matrix(int n, int m);
};
#endif //ROK04_ROK04_H ```
#ifndef ROK04_ROK04_H
#define ROK04_ROK04_H
class Array{
protected:
int* data;
int m;
public:
Array(int m);
Array& operator = (const Array& a);
virtual ~Array();
Array& operator+=(const Array& a);
virtual void setElem(int pos, int value);
virtual void stampa() const;
friend class Matrix;
};
class Matrix{
protected:
Array* data;
int n;
int m;
public:
Matrix(int n, int m);
void stampaj();
};
#endif //ROK04_ROK04_H
Cpp:
#include <iostream>
#include <ctime>
#include "rok04.h"
using namespace std;
Array::Array(int m):m(m),data( new int[m]() ){}
Array& Array::operator=(const Array& a) {
cout << "Usao" << this << endl;
for(int i = 0; i < m; i++){
data[i] = a.data[i];
}
return *this;
}
Array::~Array() {
delete[] data;
}
void Array::setElem(int pos, int value) {
try {
if(pos >= m){
cout << "Usao\n";
throw out_of_range("Index out of bounds!");
}
data[pos] = value;
} catch (out_of_range& oor){
cerr << oor.what() << endl;
}
}
void Array::print() const {
// cout << m;
for (int i = 0; i < m; ++i) {
cout << data[i] << " ";
}
cout << endl;
}
Array &Array::operator+=(const Array& a) {
int* temp = new int(m+a.m);
for(int i = 0; i < m; i++){
temp[i] = data[i];
}
for (int i = m; i < m+a.m; ++i) {
temp[i] = a.data[i-m];
}
delete[] data;
data = temp;
m = m+a.m;
return *this;
}
Matrix::Matrix(int n, int m):n(n),m(m) {
srand(time(0));
this->data=new Array(n);
for(int i=0; i<n; i++){
this->data[i].m=this->m;
this->data[i].data=new int[m];
for(int j=0; j<this->m; j++){
this->data[i].data[j]= rand()%10;
}
}
}
【问题讨论】:
-
this->data不是类类型的对象 - 它是指向Array的指针。this->data[i]使用内置的[]运算符 - 它访问data指向的Array对象的(普通)数组中的ith 元素。除了data实际上只指向一个对象,所以this->data[i]在i != 0时通过越界访问索引表现出未定义的行为。 -
在这种情况下,
this->data[i]正在执行指针运算,它等同于*(this->data + i) -
构造函数不起作用。
this->data=new Array(n);看起来像是this->data=new Array[n];的拼写错误,它会创建n类型为Array的对象,但this->data=new Array(n);只创建一个。this->data=new Array[n];对你不起作用,因为Array需要一个参数来构造。 -
如果您只希望使用
new而不是标准库,那么解决此问题的唯一简单方法是为Array定义一个默认构造函数,该构造函数初始化指向nullptr的指针,然后您可以在循环中分配实际完全构造的Array对象。