【问题标题】:Passing by reference - operator overloading [closed]通过引用传递 - 运算符重载[关闭]
【发布时间】:2012-07-14 13:32:22
【问题描述】:

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

编辑:语言:C++

【问题讨论】:

  • 用什么语言? (或者至少,在什么背景下?)。请注意,我们不会简单地为您完成作业。
  • C++。它不是家庭作业。我只是无法理解运算符重载,比如我们到底在哪里使用它?
  • 想想向量,以及如何将两个向量作为数学对象相加和相减(无论多维)。用 C++ 或其他 OOP 语言表达这一点最自然的方式是使用 + 和 -。这就是运算符重载的意义所在。
  • 不能用普通函数来完成吗? (只是问)
  • 是的,当然它可以。关键是写vec3 = vec1 + vec2; 是很自然的,重载+ 使得表达两个向量的相加非常直观。

标签: c++ operators operator-overloading


【解决方案1】:

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

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

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

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

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

基本上,请遵守一条重要规则:永远不要做任何意想不到的事情。仅当生成的符号(如“a+b”)确实是不了解重载内部结构的人所期望的时,才重载运算符。

【讨论】:

  • 非常感谢您解决了我的问题:D
  • 抱歉所有的文字,但是当我开始输入时......
  • 嗯,这是最合适且内容丰富的答案,清除了所有内容。
【解决方案2】:

cpp 的租户之一是用户类型的外观/行为应该像内置类型(如 int)。

如果可以的话

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

那你应该也能做到

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

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

【讨论】:

  • 感谢您抽出宝贵时间回答我的部分问题。
【解决方案3】:

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

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

struct IpAddress
{
    unsigned int addr;
};

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

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;

非常自然。

附言当然假设 sizeof(int) == 4 ;)

【讨论】:

  • 嗯,这是一个很好的例子。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-11
  • 1970-01-01
  • 1970-01-01
  • 2018-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多