我正在尝试实施Matrix模板。我重载了<<
,>>
和+
运算符。 <<
和>>
工作正常但+
未按预期工作。使用+
运算符后,我在最后一行得到一些随机输出。谁能告诉我有什么问题?
#include<iostream>
using namespace std;
template <class V>
class mat
{
public:
int row,col;
V **a;
mat(int r,int c)
{
row=r;
col=c;
a=new V*[r];
for(int i=0;i<row;i++)
{
a[i]=new V[col];
}
}
mat(const mat &x) //Copy constructor
{
row=x.row;
col=x.col;
a=new V*[row];
for(int i=0;i<row;i++)
{
a[i]=new V[col];
}
for(int i=0;i<row;i++)
{
for(int j=0;j<col;j++)
{
a[i][j]=x.a[i][j];
}
}
}
~mat()
{
//cout << "Deleting Matrix\n" << endl;
for(int i=0;i<row;i++)
{
delete []a[i];
}
}
friend ostream &operator<<(ostream &p,const mat &z)
{
for(int i=0;i<z.row;i++)
{
for(int j=0;j<z.col;j++)
{
p << z.a[i][j] <<" ";
}
cout << endl;
}
return p;
}
friend istream &operator>>(istream &p,mat &z)
{
for(int i=0;i<z.row;i++)
{
for(int j=0;j<z.col;j++)
{
p >> z.a[i][j];
}
}
return p;
}
mat<V> operator+(mat<V> z)
{
mat<V> b(row,col);
for(int i=0;i<row;i++)
{
for(int j=0;j<col;j++)
{
b.a[i][j]=a[i][j]+z.a[i][j];
}
}
return b;
}
};
int main()
{
mat<int> p(2,2),q(2,2),z(2,2);
cin>>p>>q;
cout<<p<<q<<endl; //working properly
z=p+q;
cout<<z<<endl; // getting wrong output here
return 0;
}
答案 0 :(得分:2)
在C ++中,我建议使用operator + =, - =,* =,/ =和类似的其他内容一样。运算符+,*, - ,/应该是外部的。
所以你可以这样做:
class A {
A &operator +=(A const &b) {
... code
return *this;
}
};
A operator+(A a1, A const &a2) {
return a1 += a2;
}
感谢vsoftco的提示
为了更准确地回答您的问题,您只是没有定义operator = 如果你做mat z = p + q;它会工作;)。 有关详细信息,请参阅下面的评论;)
答案 1 :(得分:0)
在operator+
内,您实际拥有b = (*this) + z
。但是,您只能从row
检查col
和this
。如果z
在任一维度上都较小,那么您将会超出范围。
你可以检查这个条件并找出如果发生这种情况会返回什么(或抛出异常,选择是你的):
mat<V> operator+(const mat<V>& z) const {
mat<V> b(row,col);
if (z.row != row || z.col != col) { return b; }
// ...
}
或者你也可以在尺寸上模仿mat
类,这会使两个不同大小的矩阵成为不同的类型
template <typename T, int Row, int Col>
class mat {
private:
T a[Row][Col];
// ...
};
答案 2 :(得分:0)
你的功能内部工作正常。但正如其他人在上面提到的那样,你的函数签名有问题,导致它们以一种相当奇怪的方式被调用。
我在代码中添加了一些调试输出来说明发生了什么。您应该添加这些更改,编译并运行。
#include<iostream>
using namespace std;
template <class V>
class mat
{
public:
int row,col;
V **a;
mat(int r,int c)
{
row=r;
col=c;
a=new V*[r];
for(int i=0;i<row;i++)
{
a[i]=new V[col];
for (int cc=0; cc<col;++cc)
{
a[i][cc] = -77;
}
}
}
mat(const mat &x) //Copy constructor
{
cout << "copy to this: " << this << endl;
cout << "x: " << &x << endl;
row=x.row;
col=x.col;
a=new V*[row];
for(int i=0;i<row;i++)
{
a[i]=new V[col];
}
for(int i=0;i<row;i++)
{
for(int j=0;j<col;j++)
{
a[i][j]=x.a[i][j];
}
}
}
~mat()
{
//cout << "Deleting Matrix\n" << endl;
for(int i=0;i<row;i++)
{
delete []a[i];
}
}
friend ostream &operator<<(ostream &p,const mat &z)
{
for(int i=0;i<z.row;i++)
{
for(int j=0;j<z.col;j++)
{
p << z.a[i][j] <<" ";
}
cout << endl;
}
return p;
}
friend istream &operator>>(istream &p,mat &z)
{
for(int i=0;i<z.row;i++)
{
for(int j=0;j<z.col;j++)
{
p >> z.a[i][j];
}
}
return p;
}
mat<V> operator+(mat<V> z)
{
cout << "plus to this: " << this << endl;
mat<V> b(row,col);
for(int i=0;i<row;i++)
{
for(int j=0;j<col;j++)
{
b.a[i][j]=a[i][j]+z.a[i][j];
}
}
return b;
}
};
int main()
{
mat<int> p(2,2),q(2,2),z(2,2);
cin>>p>>q;
cout<<p<<q<<endl; //working properly
cout << "Before" << endl;
cout << "p : " << &p << endl;
cout << "q : " << &q << endl;
cout << "z : " << &z << endl;
cout << "After" << endl;
z=p+q;
cout<<q<<endl;
cout<<z<<endl; // getting wrong output here
return 0;
}
当我跑步时,我看到以下输出。
Before
p : 0026F75C
q : 0026F748
z : 0026F734
After
copy to this: 0026F61C
x: 0026F748
plus to this: 0026F75C
copy to this: 0026F654
x: 0026F5E8
从这里你可以看到当行
Z = P + Q;
运行,调用复制构造函数将 q 复制到匿名对象,然后在另一个匿名对象上调用operator +函数。
最后,当退出operator +函数时,再次调用复制构造函数,将operator +函数的结果复制到第三个匿名对象。任何时候都不会复制到 z ,也不会在 p 或 q 上调用operator +函数。
此代码在退出时也会出现段错误。我认为问题在于创建匿名对象,它使用编译器创建的默认构造函数,它不设置行, col 或intialise a 强>