我有一个类似矩阵的类。 因此,用例类似于:
Matrix matrix(10,10);
matrix[0][0]=4;
//set the values for the rest of the matrix
cout<<matrix[1][2]<<endl;
代码:
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <sstream>
using namespace std;
class Matrix {
public:
Matrix(int x, int y);
class Proxy {
public:
Proxy(int* _array) : _array(_array) {
}
int &operator[](int index) const {
return _array[index];
}
private:
int* _array;
};
Proxy operator[](int index) const {
return Proxy(_arrayofarrays[index]);
}
Proxy operator[](int index) {
return Proxy(_arrayofarrays[index]);
}
const Matrix& operator=(const Matrix& othersales);
private:
int** _arrayofarrays;
int x, y;
};
Matrix::Matrix(int x, int y) {
_arrayofarrays = new int*[x];
for (int i = 0; i < x; ++i)
_arrayofarrays[i] = new int[y];
}
const Matrix& Matrix::operator=(const Matrix& othermatrix) {
new (this) Matrix(x, y);
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
_arrayofarrays[i][j] = othermatrix._arrayofarrays[i][j];
return *this;
}
int main() {
Matrix a(2, 3);
a[0][0] = 1;
a[0][1] = 2;
a[0][2] = 3;
a[1][0] = 4;
a[1][1] = 5;
a[1][2] = 6;
cout << a[1][2] << endl;
//prints out 6
const Matrix b = a;
cout << b[1][2] << endl;
a[1][2] = 3;
cout << a[1][2] << endl;
// prints out 3
cout << b[1][2] << endl;
// prints out 3 as well
}
通过调用const Matrix b = a;
我想要创建新的Matrix实例,其中包含与a
相同的值。但是,更改b
中的值会影响a
。因此,如果我更改了a
中的某个值,那么它也会在b
中更改。我不希望它表现得像这样。
所以我需要创建一个不受b
本身影响的a
副本。
那些可能是个愚蠢的问题,但对我来说,作为一个java家伙和C ++新手都是令人困惑的东西,所以感谢任何有用的建议......
答案 0 :(得分:1)
您的实施存在一些问题。简单的就是你得到的错误......
在Matrix
类中,operator[]
是非const成员函数,这意味着它只能在非const对象上执行。您的operator=
会在const &
之前截取右侧对象,因此您无法在其上调用operator[]
。这里的问题是你没有提供operator[]
的实现,它承诺不修改对象,一旦你将它添加到它应该编译的类型中。
比这更重要的是你正在泄漏记忆。当您在某个对象上调用operator=
时,您正在创建一个不同的Matrix
,而不会释放它所持有的内存。那是内存泄漏。
operator=
的实现也不是线程安全的。如果为任何内部数组分配内存失败并抛出异常,则会使对象处于既不是原始状态也不是有效状态的状态。这本身就很糟糕。
与上一个相关,只要纠正一个可能导致另一个,如果存在别名,则operator=
的实施是不安全的,也就是说,如果你失败了自己分配。第一行将泄漏内存并创建新缓冲区,然后从那里将新缓冲区复制到自身,丢失原始信息。
最后,如果您放弃使用operator[]
的要求并使用两个索引代替operator()
,则可以改进该类型的实现。用户代码必须进行调整(看起来不像二维数组),但它提供了更多的表示自由(您可以以任何您想要的方式在内部存储信息)。同时,不需要分配指针数组,然后分配int
的N个数组。您可以执行NxM ints
的单个内存分配,并执行指针算法来寻址每个位置(这与使用operator[]
/ operator()
无关),这将减少内存占用和使布局更紧凑,提高缓存性能(更不用说将动态分配数量减少M倍)
通过调用
const Matrix b = a;
我想创建Matrix的新实例,那个时刻将具有相同的a值。然而,更改a中的值会影响b。
嗯,这是我在第一次阅读中遗漏的另一个问题。表达式const Matrix b = a;
不涉及operator=
,而是复制构造函数。谷歌的另一件事:三个规则(基本上,如果你手动实现复制构造函数,赋值或析构函数之一,你可能想要实现所有这三个)。在没有定义自己的复制构造函数的情况下,编译器将隐式地为您执行一个浅复制(即复制存储在Matrix
中但不为其分配内存的指针)。复制完成后Matrix
共享相同的内存,如果析构函数释放内存,当第二个析构函数运行并尝试delete []
时,您将遇到未定义的行为已经删除的记忆。