通过引用传递 - 运算符重载

时间:2012-07-14 13:32:22

标签: c++ operators operator-overloading

在什么情况下我们在运算符重载中通过引用传递对象?为什么? 另外,在什么情况下运算符重载有用(特定情况)?

编辑:语言:C ++

3 个答案:

答案 0 :(得分:3)

您通过“引用”传递参数,因为您想要修改它们(这可能是您不希望操作符的操作,请参阅下文),或者仅仅因为传递简单指针比复制更有效整个对象。

至于“为什么超载”,这主要是一个偏好问题。有一些经典的例子,比如有一个矢量类可以让你添加矢量或类似的东西 - 基本上,这些都是很好的例子,因为它们应用了算术运算符对一些新的意义类:无论是添加整数还是向量,在两种情况下写“x + y”都是自然的表示法。这也是使用常量引用的经典原因 - 如果你写“a = b + c”你不希望b或c被修改,那么如果你的结果只是重载运算符绝对是好习惯正在做的是读者所期望的。

像智能指针(或迭代器,或其他“伪装成指针”的东西)喜欢重载运算符,例如 - >或*(取消引用运算符,而不是乘法)。同样的原因,这些对象假装是指针,它们意味着像指针一样使用,因此运算符重载用于使它们看起来更像指针。

我还重载了“,”运算符以将参数提供给字符串格式化对象 - 因为它看起来很好。 STL使用“<<”的重载和“>>”出于同样的原因;他们认为它使事情更容易阅读。

最近,我重载了一些算术运算符和“==”,所以我可以用数学符号写出线性方程。围绕它的代码从可读源代码构建系数矩阵,而不是要求开发人员编写一堆无意义的数字。这也是使用非常量引用的示例 - 但是,所有这些的结果是表示等式的矩阵中的一行,因此它正是读者所期望的。

基本上,坚持一条重要规则:不要做任何意想不到的事情。只有当“a + b”这样的结果符号确实是那些不知道你的重载内部的人才会想到它时,才会重载操作符。

答案 1 :(得分:0)

cpp的一个租户是用户类型看起来/行为类似于内置类型(如int)。

所以,如果你能做到

int a = 1;
int b = 2;
int c = a + b;

然后你也应该能够做到

UserType e = ...;
UserType d = ...;
UserType f = e + d;

因此,运算符重载允许您为用户定义的类型定义运算符+ / - * etc ...就像内置类型...

答案 2 :(得分:0)

当您想要自然地表达某种类型的对象的某些方面时,它很有用。例如,编译器知道如何将+, - ,*,/应用于int和double。但它不知道如何+应用于字符串(字符数组)。它不能总是连接数组,因为它是无稽之谈。但是对于特定的数组(char数组),连接可以用符号'+'自然表达,所以当我们写(我们可能没有,因为我们有std :: string)一些字符串类时,我们重载operator +( const MyString& rhs)它将我们的字符串添加到另一个字符串中。

但是,运算符重载也可以不仅与您自己的类型一起使用。例如,您有一个表示IPv4地址的结构:

struct IpAddress
{
    unsigned int addr;
};

你需要一些东西,这可以帮助你在屏幕上打印这个结构,或者将它写入文件。您可以添加函数to_str(),它会将addr分解为4个组件并返回字符串表示,但更自然的方法是重载运算符<< ostream:

ostream& operator<<(ostream& os, const IpAddress& ip)
{
    os 
        << (ip.addr >> 24) << '.' 
        << (0xff & (ip.addr >> 16)) << '.'
        << (0xff & (ip.addr >> 8)) << '.'
        << (0xff & ip.addr); 

    return os;
}

所以现在你没有问题将ip地址写入文件或屏幕:

IpAddress ip;
// put something to ip

cout << "your address is: " << ip << endl;

ofstream f("log.txt");
f << "address: " << ip << endl;
非常自然。

P.S。当然假设sizeof(int)== 4;)