简体   繁体   English

C ++中的引用

[英]references in C++

Once I read in a statement that 有一次我在一份声明中读到了

The language feature that "sealed the deal" to include references is operator overloading. “密封交易”以包含​​引用的语言功能是运算符重载。

Why are references needed to effectively support operator overloading?? 为什么需要引用才能有效地支持运算符重载? Any good explanation? 有什么好解释吗?

Here's what Stroustrup said in "The Design and Evolution of C++" (3.7 "references"): 这是Stroustrup在“C ++的设计和演变”(3.7“引用”)中所说的:

References were introduced primarily to support operator overloading. 引用的引用主要是为了支持运算符重载。 ... ...

C passes every function argument by value, and where passing an object by value would be inefficient or inappropriate the user can pass a pointer . C按值传递每个函数参数,并且按值传递对象的效率低或不合适,用户可以传递指针。 This strategy doesn't work where operator overloading is used. 在使用运算符重载的情况下,此策略不起作用。 In that case, notational convenience is essential because users cannot be expected to insert address-of operators if the objects are large. 在这种情况下,符号方便是必不可少的,因为如果对象很大,则不能期望用户插入地址运算符。 For example: 例如:

  a = b - c; 

is acceptable (that is, conventional) notation, but 是可接受的(即常规的)符号,但是

  a = &b - &c; 

is not. 不是。 Anyway, &b - &c already has a meaning in C, and I didn't want to change that. 无论如何, &b - &c已经在C中有意义,我不想改变它。

An obvious example would be the typical overload of ">>" as a stream extraction operator. 一个明显的例子是“>>”作为流提取操作符的典型重载。 To work as designed, this has to be able to modify both its left- and right-hand arguments. 要按设计工作,必须能够修改左手和右手参数。 The right has to be modified, because the primary purpose is to read a new value into that variable. 必须修改权限,因为主要目的是将新值读入该变量。 The left has to be modified to do things like indicating the current status of the stream. 必须修改左侧以执行指示流的当前状态的操作。

In theory, you could pass a pointer as the right-hand argument, but to do the same for the left argument would be problematic (eg when you chain operators together). 理论上,您可以将指针作为右侧参数传递,但是对于左侧参数执行相同操作会有问题(例如,当您将运算符链接在一起时)。

Edit: it becomes more problematic for the left side partly because the basic syntax of overloading is that x@y (where "@" stands for any overloaded operator) means x.opertor@(y) . 编辑:对于左侧来说变得更成问题部分是因为重载的基本语法是x @ y(其中“@”代表任何重载的运算符)意味着x.opertor@(y) Now, if you change the rules so you somehow turn that x into a pointer, you quickly run into another problem: for a pointer, a lot of those operators already have a valid meaning separate from the overload -- eg, if I translate x+2 as somehow magically working with a pointer to x , then I've produced an expression that already has a meaning completely separate from the overload. 现在,如果您更改规则以便以某种方式将x转换为指针,则会很快遇到另一个问题:对于指针,很多这些运算符已经具有与重载分开的有效含义 - 例如,如果我翻译x+2以某种方式神奇地使用指向x的指针,然后我生成了一个已经具有与重载完全分离的含义的表达式。 To work around that, you could (for example) decide that for this purpose, you'd produce a special kind of pointer that didn't support pointer arithmetic. 要解决这个问题,您可以(例如)决定为此目的,您将生成一种不支持指针算法的特殊指针。 Then you'd have to deal with x=y -- so the special pointer becomes one that you can't modify directly either, and any attempt at assigning to it ends up assigning to whatever it points at instead. 然后你必须处理x=y - 所以特殊指针变成你不能直接修改的指针,并且任何分配给它的尝试最终会分配给它所指向的任何东西。

We've only restricted them enough to support two operator overloads, but our "special pointer" is already about 90% of the way to being a reference with a different name... 我们只限制它们足以支持两个运算符重载,但是我们的“特殊指针”已经成为具有不同名称的引用的大约90%...

References constitute a standard means of specifying that the compiler should handle the addresses of objects as though they were objects themselves. 引用构成了一种标准方法,用于指定编译器应该像对象本身一样处理对象的地址。 This is well-suited to operator overloading because operations usually need to be chained in expressions; 这非常适合运算符重载,因为操作通常需要在表达式中链接; to do this with a uniform interface, ie, entirely by reference, you often would need to take the address of a temporary variable, which is illegal in C++ because pointers make no guarantee about the lifetimes of their referents. 要使用统一接口来完成此操作,即完全通过引用,您通常需要获取临时变量的地址,这在C ++中是非法的,因为指针不能保证其所指对象的生命周期。 References, on the other hand, do. 另一方面,参考文献也是如此。 Using references tells the compiler to work a certain kind of very specific magic (with const references at least) that preserves the lifetime of the referent. 使用引用告诉编译器使用某种特定的魔法(至少使用const引用)来保留指示对象的生命周期。

Typically when you're implementing an operator you want to operate directly on the operand -- not a copy of it -- but passing a pointer risks that you could delete the memory inside the operator. 通常,当您实现一个操作符时,您希望直接在操作数上操作 - 而不是它的副本 - 但是传递一个指针就有可能删除操作符内的内存。 (Yes, it would be stupid, but it would be a significant danger nonetheless.) References allow for a convenient way of allowing pointer-like access without the "assignment of responsibility" that passing pointers incurs. (是的,这将是愚蠢的,但它仍然是一个重大的危险。)引用允许一种方便的方式允许指针式访问,而没有传递指针的“责任分配”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM