C++运算符重载无法输出+运算
C++ operator overloading fails to output + operation
我正在学习 C++ 并尝试为矩阵编写 C++ class,我将矩阵存储为一维 C 数组。为此,我定义了一个 element
成员函数来根据矩阵元素在数组中的位置访问它们。然后我重载了 <<
和 +
运算符来处理矩阵的显示和添加。 <<
运算符按预期工作,如下例所示:
#include<iostream>
class matrix {
friend std::ostream & operator<<(std::ostream &os, matrix &M);
private:
int rows{}, columns{};
double *array {nullptr};
public:
matrix(int rows, int columns);
~matrix() {}
double & element(int r, int c);
matrix operator+(matrix &M)
{
matrix N(rows, columns);
if (M.rows!=rows || M.columns!=columns){
std::cout << "ERROR: DIMENSIONS OF MATRICES DO NOT MATCH" << std::endl;
}
else{
for (int i{1}; i<=M.rows; i++)
for (int j{1}; j<=M.columns; j++){
N.element(i,j) = element(i,j) + M.element(i,j);
}
}
return N;
}
};
matrix::matrix(int r, int c)
{
rows = r;
columns = c;
array = new double[rows*columns];
for(int i{0}; i<rows*columns; i++) array[i]=0.0;
}
double & matrix::element(int i, int j)
{
int loc{0};
loc = (j-1) + (i-1)*columns;
return array[loc];
}
std::ostream & operator<<(std::ostream &os, matrix &M)
{
for (int i{1}; i<=M.rows; i++){
os << "[ ";
for (int j{1}; j<=M.columns; j++){
os << M.element(i,j) << " ";
}
os << "] \n";
}
return os;
}
int main() {
matrix A(2,2);
matrix B(2,2);
A.element(1,1) = 1;
A.element(1,2) = 2;
A.element(2,1) = 3;
A.element(2,2) = 4;
B.element(1,1) = 1;
B.element(1,2) = 2;
B.element(2,1) = 3;
B.element(2,2) = 4;
std::cout << A << std::endl;
std::cout << B << std::endl;
return 0;
}
然后我无法显示两个矩阵的加法:
std::cout << A+B << std::endl;
但是,如果我在显示它们的总和之前分解操作并分别添加矩阵,我会得到正确的输出,这让我相信 +
运算符也能正常工作:
matrix C(2,2);
C = A+B;
std::cout << C << std::endl;
该错误似乎表明将矩阵元素转换为 ostream 时可能存在问题,但奇怪的是上述变通解决方案是否有效。
您的 <<
运算符将对矩阵的非常量引用作为参数。这意味着它不能引用临时对象。
A+B
的结果是一个临时对象,如果你不将它分配给某些东西的话。
所以你需要改变这个:
std::ostream & operator<<(std::ostream &os, matrix &M);
进入这个:
std::ostream & operator<<(std::ostream &os, const matrix &M);
您的 +
接线员可能迟早会遇到同样的问题:
matrix operator+(matrix &M)
应该是
// Both `M` and `*this` should be const
matrix operator+(const matrix &M) const
当然你的 element
方法会遇到问题,它只能作用于非常量对象,所以你还需要一个作用于常量对象的变体:
class matrix
{
....
public:
double & element(int r, int c);
double element(int r, int c) const;
...
}
您不能对临时对象进行非const
引用。您正在尝试使用临时 (A+B
) 调用 operator<<
,但重载 operator<<
的签名采用非 const
引用,因此您的函数无效候选人。
要解决此问题,您需要进行一些更改。首先,让重载的 <<
运算符对矩阵进行 const
引用。并且不要忘记在 class 声明中修复 friend
签名。
std::ostream & operator<<(std::ostream &os, const matrix &M);
只是这样做仍然会导致错误,因为 element
方法只为非 const
对象定义。您需要为 element
添加一个重载,它作用于 const
matrix
es(并且不会让您修改返回的元素)。
double matrix::element(int i, int j) const
{
int loc = (j-1) + (i-1)*columns;
return array[loc];
}
你的operator<<
和operator+
都需要通过const引用来获取输入matrix
,这样他们才能接受临时matrix
对象作为输入。
此外,operator+
应该是 const
限定的,因为它不会修改 this
的内容。 element()
应该有一个 const
限定的重载,这样它就可以提供对 const matrix
对象的只读访问。
根据 Rule of 3/5/0,您还缺少复制构造函数、复制赋值运算符、移动构造函数和移动赋值运算符。而且,你的析构函数根本没有释放 C 数组,所以它被泄露了。
试试这个:
#include <iostream>
#include <stdexcept>
#include <utility>
class matrix {
friend std::ostream& operator<<(std::ostream &os, const matrix &M);
private:
int rows{}, columns{};
double* array{nullptr};
public:
matrix(int rows, int columns);
matrix(const matrix &M);
matrix(matrix &&M);
~matrix();
matrix& operator=(matrix M);
double& element(int r, int c);
double element(int r, int c) const;
matrix operator+(const matrix &M) const;
matrix& operator+=(const matrix &M);
};
matrix::matrix(int r, int c)
: rows(r), columns(c)
{
size_t size = rows*columns;
array = new double[size];
for(size_t i = 0; i < size; ++i)
array[i] = 0.0;
}
matrix::matrix(const matrix &M)
: rows(M.rows), columns(M.columns)
{
size_t size = rows*columns;
array = new double[size];
for(size_t i = 0; i < size; ++i)
array[i] = M.array[i];
}
matrix::matrix(matrix &&M)
: rows(M.rows), columns(M.columns), array(M.array)
{
M.rows = M.columns = 0;
M.array = nullptr;
}
matrix::~matrix()
{
delete[] array;
}
matrix& operator=(matrix M)
{
std::swap(rows, M.rows);
std::swap(columns, M.columns);
std::swap(array, M.array);
return *this;
}
double& matrix::element(int r, int c)
{
// TODO: do bounds checking here...
size_t loc = ((r-1)*columns) + (c-1);
return array[loc];
}
double matrix::element(int r, int c) const
{
// TODO: do bounds checking here...
size_t loc = ((r-1)*columns) + (c-1);
return array[loc];
}
std::ostream & operator<<(std::ostream &os, const matrix &M)
{
for (int r = 1; r <= M.rows; ++r){
os << "[ ";
for (int c = 1; c <= M.columns; ++c){
os << M.element(r,c) << " ";
}
os << "]\n";
}
/* alternatively...
size_t loc = 0;
for (int r = 0; r < M.rows; ++r){
os << "[ ";
for (int c = 0; c < M.columns; ++c){
os << M.array[loc++] << " ";
}
os << "]\n";
}
*/
return os;
}
matrix matrix::operator+(const matrix &M) const
{
matrix N(*this);
N += M;
return N;
}
matrix& matrix::operator+=(const matrix &M)
{
if (M.rows != rows || M.columns != columns){
throw std::runtime_error("DIMENSIONS OF MATRICES DO NOT MATCH");
}
for (int r = 1; r <= rows; ++r)
for (int c = 1; c <= columns; ++c){
element(r,c) += M.element(r,c);
}
}
/* alternatively:
size_t size = rows*columns;
for (size_t i = 0; i < size; ++i)
array[i] += M.array[i];
}
*/
return *this;
}
int main() {
matrix A(2,2);
matrix B(2,2);
A.element(1,1) = 1;
A.element(1,2) = 2;
A.element(2,1) = 3;
A.element(2,2) = 4;
B.element(1,1) = 1;
B.element(1,2) = 2;
B.element(2,1) = 3;
B.element(2,2) = 4;
std::cout << A << std::endl;
std::cout << B << std::endl;
return 0;
}
我正在学习 C++ 并尝试为矩阵编写 C++ class,我将矩阵存储为一维 C 数组。为此,我定义了一个 element
成员函数来根据矩阵元素在数组中的位置访问它们。然后我重载了 <<
和 +
运算符来处理矩阵的显示和添加。 <<
运算符按预期工作,如下例所示:
#include<iostream>
class matrix {
friend std::ostream & operator<<(std::ostream &os, matrix &M);
private:
int rows{}, columns{};
double *array {nullptr};
public:
matrix(int rows, int columns);
~matrix() {}
double & element(int r, int c);
matrix operator+(matrix &M)
{
matrix N(rows, columns);
if (M.rows!=rows || M.columns!=columns){
std::cout << "ERROR: DIMENSIONS OF MATRICES DO NOT MATCH" << std::endl;
}
else{
for (int i{1}; i<=M.rows; i++)
for (int j{1}; j<=M.columns; j++){
N.element(i,j) = element(i,j) + M.element(i,j);
}
}
return N;
}
};
matrix::matrix(int r, int c)
{
rows = r;
columns = c;
array = new double[rows*columns];
for(int i{0}; i<rows*columns; i++) array[i]=0.0;
}
double & matrix::element(int i, int j)
{
int loc{0};
loc = (j-1) + (i-1)*columns;
return array[loc];
}
std::ostream & operator<<(std::ostream &os, matrix &M)
{
for (int i{1}; i<=M.rows; i++){
os << "[ ";
for (int j{1}; j<=M.columns; j++){
os << M.element(i,j) << " ";
}
os << "] \n";
}
return os;
}
int main() {
matrix A(2,2);
matrix B(2,2);
A.element(1,1) = 1;
A.element(1,2) = 2;
A.element(2,1) = 3;
A.element(2,2) = 4;
B.element(1,1) = 1;
B.element(1,2) = 2;
B.element(2,1) = 3;
B.element(2,2) = 4;
std::cout << A << std::endl;
std::cout << B << std::endl;
return 0;
}
然后我无法显示两个矩阵的加法:
std::cout << A+B << std::endl;
但是,如果我在显示它们的总和之前分解操作并分别添加矩阵,我会得到正确的输出,这让我相信 +
运算符也能正常工作:
matrix C(2,2);
C = A+B;
std::cout << C << std::endl;
该错误似乎表明将矩阵元素转换为 ostream 时可能存在问题,但奇怪的是上述变通解决方案是否有效。
您的 <<
运算符将对矩阵的非常量引用作为参数。这意味着它不能引用临时对象。
A+B
的结果是一个临时对象,如果你不将它分配给某些东西的话。
所以你需要改变这个:
std::ostream & operator<<(std::ostream &os, matrix &M);
进入这个:
std::ostream & operator<<(std::ostream &os, const matrix &M);
您的 +
接线员可能迟早会遇到同样的问题:
matrix operator+(matrix &M)
应该是
// Both `M` and `*this` should be const
matrix operator+(const matrix &M) const
当然你的 element
方法会遇到问题,它只能作用于非常量对象,所以你还需要一个作用于常量对象的变体:
class matrix
{
....
public:
double & element(int r, int c);
double element(int r, int c) const;
...
}
您不能对临时对象进行非const
引用。您正在尝试使用临时 (A+B
) 调用 operator<<
,但重载 operator<<
的签名采用非 const
引用,因此您的函数无效候选人。
要解决此问题,您需要进行一些更改。首先,让重载的 <<
运算符对矩阵进行 const
引用。并且不要忘记在 class 声明中修复 friend
签名。
std::ostream & operator<<(std::ostream &os, const matrix &M);
只是这样做仍然会导致错误,因为 element
方法只为非 const
对象定义。您需要为 element
添加一个重载,它作用于 const
matrix
es(并且不会让您修改返回的元素)。
double matrix::element(int i, int j) const
{
int loc = (j-1) + (i-1)*columns;
return array[loc];
}
你的operator<<
和operator+
都需要通过const引用来获取输入matrix
,这样他们才能接受临时matrix
对象作为输入。
此外,operator+
应该是 const
限定的,因为它不会修改 this
的内容。 element()
应该有一个 const
限定的重载,这样它就可以提供对 const matrix
对象的只读访问。
根据 Rule of 3/5/0,您还缺少复制构造函数、复制赋值运算符、移动构造函数和移动赋值运算符。而且,你的析构函数根本没有释放 C 数组,所以它被泄露了。
试试这个:
#include <iostream>
#include <stdexcept>
#include <utility>
class matrix {
friend std::ostream& operator<<(std::ostream &os, const matrix &M);
private:
int rows{}, columns{};
double* array{nullptr};
public:
matrix(int rows, int columns);
matrix(const matrix &M);
matrix(matrix &&M);
~matrix();
matrix& operator=(matrix M);
double& element(int r, int c);
double element(int r, int c) const;
matrix operator+(const matrix &M) const;
matrix& operator+=(const matrix &M);
};
matrix::matrix(int r, int c)
: rows(r), columns(c)
{
size_t size = rows*columns;
array = new double[size];
for(size_t i = 0; i < size; ++i)
array[i] = 0.0;
}
matrix::matrix(const matrix &M)
: rows(M.rows), columns(M.columns)
{
size_t size = rows*columns;
array = new double[size];
for(size_t i = 0; i < size; ++i)
array[i] = M.array[i];
}
matrix::matrix(matrix &&M)
: rows(M.rows), columns(M.columns), array(M.array)
{
M.rows = M.columns = 0;
M.array = nullptr;
}
matrix::~matrix()
{
delete[] array;
}
matrix& operator=(matrix M)
{
std::swap(rows, M.rows);
std::swap(columns, M.columns);
std::swap(array, M.array);
return *this;
}
double& matrix::element(int r, int c)
{
// TODO: do bounds checking here...
size_t loc = ((r-1)*columns) + (c-1);
return array[loc];
}
double matrix::element(int r, int c) const
{
// TODO: do bounds checking here...
size_t loc = ((r-1)*columns) + (c-1);
return array[loc];
}
std::ostream & operator<<(std::ostream &os, const matrix &M)
{
for (int r = 1; r <= M.rows; ++r){
os << "[ ";
for (int c = 1; c <= M.columns; ++c){
os << M.element(r,c) << " ";
}
os << "]\n";
}
/* alternatively...
size_t loc = 0;
for (int r = 0; r < M.rows; ++r){
os << "[ ";
for (int c = 0; c < M.columns; ++c){
os << M.array[loc++] << " ";
}
os << "]\n";
}
*/
return os;
}
matrix matrix::operator+(const matrix &M) const
{
matrix N(*this);
N += M;
return N;
}
matrix& matrix::operator+=(const matrix &M)
{
if (M.rows != rows || M.columns != columns){
throw std::runtime_error("DIMENSIONS OF MATRICES DO NOT MATCH");
}
for (int r = 1; r <= rows; ++r)
for (int c = 1; c <= columns; ++c){
element(r,c) += M.element(r,c);
}
}
/* alternatively:
size_t size = rows*columns;
for (size_t i = 0; i < size; ++i)
array[i] += M.array[i];
}
*/
return *this;
}
int main() {
matrix A(2,2);
matrix B(2,2);
A.element(1,1) = 1;
A.element(1,2) = 2;
A.element(2,1) = 3;
A.element(2,2) = 4;
B.element(1,1) = 1;
B.element(1,2) = 2;
B.element(2,1) = 3;
B.element(2,2) = 4;
std::cout << A << std::endl;
std::cout << B << std::endl;
return 0;
}