在“The C ++ Programming Language”一书中,作者给出了以下示例和几个声明。
class Matrix {
double m[4][4];
public:
Matrix( );
friend Matrix operator+(const Matrix&, const Matrix&)
};
Matrix operator+(const Matrix& arg1, const Matrix& arg2)
{
Matrix sum;
for (int i=0; i<4; i++)
sum.m[i][j ]=arg1.m[i][j]+arg2.m[i][j];
return sum;
}
这本书声称
引用允许使用涉及大型对象的常用算术运算符的表达式而无需过多复制。无法使用指针,因为无法重新定义应用于指针的运算符的含义。
我不明白上述陈述中“过度复制”是指什么。并且对于“指针不能被使用因为不可能重新定义应用于指针的运算符的含义”的陈述,我只是完全迷失了。感谢您的解释。
答案 0 :(得分:7)
如果operator+
被声明为按值获取其操作数,例如,
Matrix operator+(Matrix arg1, Matrix arg2)
然后必须将arg1
和arg2
的副本传递给函数。一个简单的矩阵加法,例如,
Matrix x, y;
x + y;
需要制作x
和y
的副本;实际上,你最终必须复制32 double
s,虽然在这种情况下并不是非常昂贵,但也不是特别便宜。当你通过引用参数时,不需要复制。
请注意,某些运算符重载必须通过引用获取其参数。作为一个常见示例,请考虑<<
流插入运算符:它必须通过引用获取其std::istream
操作数,因为无法复制流。
指针不能被使用,因为运算符不能为指针重载:每个运算符重载的至少一个操作数必须是类或枚举类型。即使你可以使用指针,语法也会非常尴尬;如上所示,您需要使用x + y
。
&x + &y
答案 1 :(得分:1)
“过度复制”部分很简单。如果参数列表中没有&
,则传入时将复制矩阵。
引用在某些方面类似于C ++指针,它们几乎总是在内部使用指针实现。本书指出,其中一个不同之处在于,您可以对类的实例的引用使用operator overloading。
但是,您不能执行以下(或任何等效语法):
Matrix operator+(const Matrix *arg1, const Matrix *arg2)
所以你不能写:
Matrix *a, *b, *c;
c = a + b;
答案 2 :(得分:0)
不允许用户定义的运算符用于内置类型(如指针或整数)的原因当然是他们已经有运算符为语言定义了这些运算符。