运算符重载

发布于 2024-09-08 10:49:34 字数 63 浏览 3 评论 0原文

从语言设计的角度来看,什么类型的实践是支持运算符重载的?

有什么优点和优点?缺点(如果有的话)?

From language design point of view , What type of practice is supporting operator overloading?

What are the pros & cons (if any) ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

溇涏 2024-09-15 10:49:34

编辑:有人提到,std::complex 是一个比 std::string 更好地使用运算符重载的例子,所以我也提供了一个示例:

std::complex<double> c;
c = 10.0;
c += 2.0;
c = std::complex<double>(10.0, 1.0);
c = c + 10.0;

除了构造函数语法之外,它的外观和行为就像任何其他内置类型一样。


主要优点是您可以创建类似于内置类型的新类型。一个很好的例子是 C++ 中的 std::string (参见上面的更好的例子)。这是在库中实现的,不是基本类型。然而你可以这样写:

std::string s = "hello"
s += " world";
if(s == "hello world") {
    //....
}

缺点是它很容易被滥用。运算符重载的错误选择可能会意外地导致代码效率低下或不清晰。想象一下,如果 std::list 有一个 operator[]。您可能会想写:

for(int i = 0; i < l.size(); ++i) {
    l[i] += 10;
}

这是一个 O(n^2) 算法!哎哟。幸运的是,std::list没有operator[],因为它被认为是一个有效的操作。

EDIT: it has been mentioned that std::complex is a much better example than std::string for "good use" of operator overloading, so I am including an example of that as well:

std::complex<double> c;
c = 10.0;
c += 2.0;
c = std::complex<double>(10.0, 1.0);
c = c + 10.0;

Aside from the constructor syntax, it looks and acts just like any other built in type.


The primary pro is that you can create new types which act like the built in types. A good example of this is std::string (see above for a better example) in c++. Which is implemented in the library and is not a basic type. Yet you can write things like:

std::string s = "hello"
s += " world";
if(s == "hello world") {
    //....
}

The downside is that it is easy to abuse. Poor choices in operator overloading can lead to accidentally inefficient or unclear code. Imagine if std::list had an operator[]. You may be tempted to write:

for(int i = 0; i < l.size(); ++i) {
    l[i] += 10;
}

that's an O(n^2) algorithm! Ouch. Fortunately, std::list does not have operator[] since it is assumed to be an efficient operation.

浮萍、无处依 2024-09-15 10:49:34

最初的驱动力通常是数学。程序员希望通过编写 a + b 来添加向量和四元数,并使用 M * v 将矩阵乘以向量。

它的范围比这要广泛得多。例如,智能指针在语法上看起来像普通指针,流看起来有点像 Unix 管道,并且可以像数组一样使用各种自定义数据结构(甚至可以使用字符串作为索引!)。

重载背后的一般原则是允许库实现者以无缝的方式增强语言。这既是一种力量,也是一种诅咒。它提供了一种非常强大的方法,使该语言看起来比开箱即用的更丰富,但它也很容易被滥用(比许多其他 C++ 功能更容易被滥用)。

The initial driver is usually maths. Programmers want to add vectors and quaternions by writing a + b and multiply matrices by vectors with M * v.

It has much broader scope than that. For instance, smart pointers look syntactically like normal pointers, streams can look a bit like Unix pipes and various custom data structures can be used as if they were arrays (with strings as indexes, even!).

The general principle behind overloading is to allow library implementors to enhance the language in a seamless way. This is both a strength and a curse. It provides a very powerful way to make the language seem richer than it is out of the box, but it is also highly vulnerable to abuse (more so than many other C++ features).

记忆消瘦 2024-09-15 10:49:34

优点:您最终可以获得更易于阅读的代码。很少有人会争辩说:

BigDecimal a = x.add(y).divide(z).plus(m.times(n));

和缺点一样容易阅读

BigDecimal a = ((x + y) / z) + (m * n); // Brackets added for clarity

:很难说出它的名称。我似乎记得在C++中,形式的语句

a = b[i];

最终可以执行7个自定义操作,尽管我不记得它们是什么。我可能对这个例子有点“偏离”,但原则是正确的——运算符重载和自定义转换可以“隐藏”代码。

Pros: you can end up with code which is simpler to read. Few people would argue that:

BigDecimal a = x.add(y).divide(z).plus(m.times(n));

is as easy to read as

BigDecimal a = ((x + y) / z) + (m * n); // Brackets added for clarity

Cons: it's harder to tell what's being called. I seem to remember that in C++, a statement of the form

a = b[i];

can end up performing 7 custom operations, although I can't remember what they all are. I may be slightly "off" on the example, but the principle is right - operator overloading and custom conversions can "hide" code.

听风吹 2024-09-15 10:49:34

您可以使用语法(即 C++ 中的流)做一些有趣的技巧,并且可以使一些代码非常简洁。但是,您可能会导致代码变得非常难以调试和理解。您必须时刻警惕不同类型对象的各种操作员的影响。

You can do some interesting tricks with syntax (i.e. streams in C++) and you can make some code very concise. However, you can have the effect of making code very difficult to debug and understand. You sort of have to constantly be on your guard about the effects of various operators of different kinds of objects.

油焖大侠 2024-09-15 10:49:34

您可能会将运算符重载视为一种方法/函数重载。它是面向对象语言中多态性的一部分。

通过重载,每个类的对象都像原始类型一样工作,这使得类使用起来更加自然,就像 1 + 2 一样简单。

比如说一个复数类,Complex。
复数(1,2i) + 复数(2,3i) 产生复数(3,5i)。
5 + Complex(3, 2i) 生成 Complex(8, 2i)。
Complex(2, 4i) + -1.8 产生 Complex(0.2, 4i)。

以这种方式使用类要容易得多。如果没有运算符重载,则必须使用一堆类方法来表示“add”,并使表示法变得笨拙。

应该仔细定义运算符重载;否则,就会出现混乱。例如,“+”运算符通常用于添加数字、时间、日期或数组或文本的串联。将“+”运算符添加到 Mouse 或 Car 类可能没有任何意义。有时,某些超载对某些人来说可能看起来不自然。例如,数组(1,2,3) + 数组(3,4,5)。有些人可能期望 Array(4,6,8),但有些人期望 Array(1,2,3,3,4,5)。

You might deem operator overloading as a kind of method/function overloading. It is part of polymorphism in object oriented language.

With overloading, each class of objects work like primitive types, which make classes more natural to use, just as easy as 1 + 2.

Say a complex number class, Complex.
Complex(1,2i) + Complex(2,3i) yields Complex(3,5i).
5 + Complex(3, 2i) yields Complex(8, 2i).
Complex(2, 4i) + -1.8 yields Complex(0.2, 4i).

It is much easier to use class this way. If there is no operator overloading, you have to use a bunch of class methods to denote 'add' and make the notation clumsy.

The operator overloading ought to be defined carefully; otherwise, comes confusion. For example, '+' operator is natural to adding numbers, time, date, or concatenation of array or text. Adding '+' operator to a class of Mouse or Car might not make any sense. Sometimes some overloading might not be seem natural to some people. For example, Array(1,2,3) + Array(3,4,5). Some might expect Array(4,6,8) but some expect Array(1,2,3,3,4,5).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文