I do not quite understand the difference between a C# reference and a pointer. They both point to a place in memory don't they? The only difference I can figure out is that pointers are not as clever, cannot point to anything on the heap, are exempt from garbage collection, and can only reference structs or base types.
我不太了解C#引用和指针之间的区别。他们都指向记忆中的一个地方不是吗?我能弄清楚的唯一区别是指针不是那么聪明,不能指向堆上的任何东西,免于垃圾收集,只能引用结构或基类型。
One of the reasons I ask is that there is a perception that people need to understand pointers well (from C, I guess) to be a good programmer. A lot of people who learn higher level languages miss this out and therefore have this weakness.
我问的一个原因是,有一种观念认为人们需要很好地理解指针(从C,我猜)是一个优秀的程序员。许多学习更高级语言的人都错过了这个,因此有这个弱点。
I just don't get what is so complex about a pointer? It is basically just a reference to a place in memory is it not? It can return its location and interact with the object in that location directly?
我只是不知道指针的复杂程度如何?它基本上只是对内存中某个地方的引用不是吗?它可以返回它的位置并直接与该位置的对象进行交互?
Have I missed a massive point?
我错过了一个重点吗?
10 个解决方案
#1
C# references can, and will be relocated by garbage collector but normal pointers are static. This is why we use fixed
keyword when acquiring a pointer to an array element, to prevent it from getting moved.
C#引用可以并且将由垃圾收集器重定位,但是普通指针是静态的。这就是为什么我们在获取指向数组元素的指针时使用fixed关键字,以防止它被移动。
EDIT: Conceptually, yes. They are more or less the same.
编辑:从概念上讲,是的。它们或多或少相同。
#2
There is a slight, yet extremely important, distinction between a pointer and a reference. A pointer points to a place in memory while a reference points to an object in memory. Pointers are not "type safe" in the sense that you cannot guarantee the correctness of the memory they point at.
指针和引用之间存在轻微但非常重要的区别。指针指向内存中的某个位置,而引用指向内存中的对象。指针不是“类型安全”,因为您无法保证它们所指向的内存的正确性。
Take for example the following code
以下面的代码为例
int* p1 = GetAPointer();
This is type safe in the sense that GetAPointer must return a type compatible with int*. Yet there is still no guarantee that *p1 will actually point to an int. It could be a char, double or just a pointer into random memory.
从某种意义上说,这是类型安全的,GetAPointer必须返回与int *兼容的类型。然而,仍然无法保证* p1实际上会指向一个int。它可以是char,double或只是指向随机存储器的指针。
A reference however points to a specific object. Objects can be moved around in memory but the reference cannot be invalidated (unless you use unsafe code). References are much safer in this respect than pointers.
然而,引用指向特定对象。对象可以在内存中移动,但引用不能失效(除非您使用不安全的代码)。在这方面,参考文献比指针更安全。
string str = GetAString();
In this case str has one of two state 1) it points to no object and hence is null or 2) it points to a valid string. That's it. The CLR guarantees this to be the case. It cannot and will not for a pointer.
在这种情况下,str具有两种状态之一1)它指向没有对象,因此为空或2)它指向有效的字符串。而已。 CLR保证了这种情况。它不能也不会用于指针。
#3
A reference is an "abstract" pointer: you can't do arithmetic with a reference and you can't play any low-level tricks with its value.
引用是一个“抽象”指针:你不能用引用算术,你不能用它的值玩任何低级技巧。
#4
First I think you need to define a "Pointer" in your sematics. Do you mean the pointer you can create in unsafe code with fixed? Do you mean an IntPtr that you get from maybe a native call or Marshal.AllocHGlobal? Do you mean a GCHandle? The all are essentially the same thing - a representation of a memory address where something is stored - be it a class, a number, a struct, whatever. And for the record, they certainly can be on the heap.
首先,我认为你需要在你的sematics中定义一个“指针”。你的意思是你可以用固定的不安全代码创建指针吗?你的意思是你可能从本机电话或Marshal.AllocHGlobal得到的IntPtr?你的意思是GCHandle?所有这些都是基本相同的东西 - 存储内容的存储器地址的表示 - 无论是类,数字,结构还是其他。而且为了记录,他们当然可以在堆上。
A pointer (all of the above versions) is a fixed item. The GC has no idea what is at that address, and therefore has no ability to manage the memory or life of the object. That means you lose all of the benefits of a garbage collected system. You must manually manage the object memory and you have the potential for leaks.
指针(以上所有版本)都是固定项。 GC不知道该地址是什么,因此无法管理对象的内存或生命。这意味着您将失去垃圾收集系统的所有好处。您必须手动管理对象内存,否则可能会发生泄漏。
A reference on the other hand is pretty much a "managed pointer" that the GC knows about. It's still an address of an object, but now the GC knows details of the target, so it can move it around, do compactions, finalize, dispose and all of the other nice stuff a managed environment does.
另一方面,引用几乎是GC知道的“托管指针”。它仍然是一个对象的地址,但现在GC知道目标的细节,因此它可以移动它,进行压缩,最终化,处置以及托管环境所做的所有其他好东西。
The major difference, really, is in how and why you would use them. For a vast majority of cases in a managed language, you're going to use an object reference. Pointers become handy for doing interop and the rare need for really fast work.
实际上,主要区别在于您如何以及为何使用它们。对于托管语言中的绝大多数情况,您将使用对象引用。指针对于互操作以及对快速工作的罕见需求变得很方便。
Edit: In fact here's a good example of when you might use a "pointer" in managed code - in this case it's a GCHandle, but the exact same thing could have been done with AllocHGlobal or by using fixed on a byte array or struct. I tend to prefer the GCHandle becasue it feels more ".NET" to me.
编辑:事实上,这是一个很好的例子,说明何时可以在托管代码中使用“指针” - 在这种情况下它是一个GCHandle,但完全相同的事情可能是使用AllocHGlobal或使用固定的字节数组或结构。我倾向于选择GCHandle,因为它对我来说感觉更像“.NET”。
#5
Pointers point to a location in the memory address space. References point to a data structure. Data structures all moved all the time (well, not that often, but every now and then) by the garbage collector (for compacting memory space). Also, as you said, data structures without references will get garbage collected after a while.
指针指向内存地址空间中的位置。引用指向数据结构。数据结构都被垃圾收集器(用于压缩内存空间)一直移动(好吧,不是经常,但是时不时地)。另外,正如您所说,没有引用的数据结构将在一段时间后收集垃圾。
Also, pointers are only usable in unsafe context.
此外,指针仅在不安全的上下文中可用。
#6
I think it's important for developers to understand the concept of a pointer—that is, to understand indirection. That doesn't mean they necessarily have to use pointers. It's also important to understand that the concept of a reference differs from the concept of pointer, although only subtly, but that the implementation of a reference almost always is a pointer.
我认为对于开发人员来说理解指针的概念很重要 - 也就是了解间接性。这并不意味着他们必须使用指针。同样重要的是要理解引用的概念与指针的概念不同,尽管只是巧妙地,但是引用的实现几乎总是指针。
That is to say, a variable holding a reference is just a pointer-sized block of memory holding a pointer to the object. However, this variable cannot be used in the same way that a pointer variable can be used. In C# (and C, and C++, ...), a pointer can be indexed like an array, but a reference cannot. In C#, a reference is tracked by the garbage collector, a pointer cannot be. In C++, a pointer can be reassigned, a reference cannot. Syntactically and semantically, pointers and references are quite different, but mechanically, they're the same.
也就是说,保存引用的变量只是一个指针大小的内存块,其中包含指向该对象的指针。但是,此变量的使用方式与使用指针变量的方式不同。在C#(和C和C ++,...)中,指针可以像数组一样索引,但引用不能。在C#中,垃圾收集器跟踪引用,指针不能。在C ++中,指针可以重新分配,引用不能。在语法和语义上,指针和引用是完全不同的,但在机械上,它们是相同的。
#7
A pointer can point to any byte in the address space of the application. A reference is tightly constrained and controlled and managed by the .NET environment.
指针可以指向应用程序地址空间中的任何字节。 .NET环境严格限制和控制和管理引用。
#8
A major difference between a reference and a pointer is that a pointer is a collection of bits whose content only matters when it is actively being used as a pointer, while a reference encapsulates not only a set of bits, but also some metadata which keeps the underlying framework informed of its existence. If a pointer exists to some object in memory, and that object is deleted but the pointer is not erased, the pointer's continued existence won't cause any harm unless or until an attempt is made to access the memory to which it points. If no attempt is made to use the pointer, nothing will care about its existence. By contrast, reference-based frameworks like .NET or the JVM require that it always be possible for the system to identify every object reference in existence, and every object reference in existence must always either be null
or else identify an object of its proper type.
引用和指针之间的主要区别在于指针是位的集合,其内容仅在主动用作指针时才重要,而引用不仅封装了一组位,而且还封装了一些保留基础框架告知其存在。如果指针存在于内存中的某个对象,并且该对象被删除但指针未被擦除,则指针的继续存在不会造成任何伤害,除非或直到尝试访问它指向的内存。如果没有尝试使用指针,没有什么可以关心它的存在。相比之下,基于引用的框架(如.NET或JVM)要求系统始终可以识别存在的每个对象引用,并且现有的每个对象引用必须始终为null或者标识其正确类型的对象。
Note that each object reference actually encapsulates two kinds of information: (1) the field contents of the object it identifies, and (2) the set of other references to the same object. Although there isn't any mechanism by which the system can quickly identify all the references that exist to an object, the set of other references that exist to an object may often be the most important thing encapsulated by a reference (this is especially true when things of type Object
are used as things like lock tokens). Although the system keeps a few bits of data for each object for use in GetHashCode
, objects have no real identity beyond the set of references that exist to them. If X
holds the only extant reference to an object, replacing X
with a reference to a new object with the same field contents will have no identifiable effect except to change the bits returned by GetHashCode()
, and even that effect isn't guaranteed.
请注意,每个对象引用实际上都封装了两种信息:(1)它标识的对象的字段内容,以及(2)对同一对象的其他引用的集合。虽然系统没有任何机制可以快速识别对象存在的所有引用,但是对象存在的其他引用集通常可能是引用封装的最重要的东西(尤其是当类型为Object的东西用作锁定令牌之类的东西。尽管系统为每个对象保留了一些数据用于GetHashCode,但是对象除了存在于它们之外的引用集之外没有真正的标识。如果X保存对象的唯一现存引用,则使用相同字段内容替换对具有相同字段内容的新对象的X将没有可识别的效果,除非更改GetHashCode()返回的位,甚至不能保证该效果。
#9
The thing about pointers that makes them somewhat complex is not what they are, but what you can do with them. And when you have a pointer to a pointer to a pointer. That's when it really starts to get fun.
关于指针使它们有点复杂的事情不是它们的本质,而是你可以用它们做什么。当你有一个指向指针的指针时。那是真正开始变得有趣的时候。
#10
One of the biggest benefits of references over pointers is greater simplicity and readability. As always when you simplify something you make it easier to use but at the cost of flexibility and control you get with the low-level stuff (as other people have mentioned).
引用优于指针的最大好处之一是更高的简单性和可读性。与往常一样,当你简化某些东西时,你会更容易使用,但是以灵活性和控制为代价,你会得到低级别的东西(正如其他人提到的那样)。
Pointers are often criticized for being 'ugly'.
指针经常被批评为“丑陋”。
class* myClass = new class();
Now everytime you use it you have to dereference it first either by
现在,每次使用它时,您必须首先取消引用它
myClass->Method() or (*myClass).Method()
Despite losing some readability and adding complexity, people still needed to use pointers often as parameters so you could modify the actual object (instead of passing by value) and for the performance gain of not having to copy huge objects.
尽管失去了一些可读性并增加了复杂性,人们仍然需要经常使用指针作为参数,这样你就可以修改实际的对象(而不是通过值传递)以及不必复制大对象的性能提升。
To me this is why references were 'born' in the first place to provide the same benefit as pointers but without all that pointer syntax. Now you can pass the actual object (not just its value) AND you have a more readable, normal way of interacting with the object.
对我而言,这就是为什么引用首先是“天生的”,以提供与指针相同的好处,但没有所有指针语法。现在你可以传递实际的对象(而不仅仅是它的值)并且你有一个更可读,更正常的方式与对象交互。
MyMethod(&type parameter)
{
parameter.DoThis()
parameter.DoThat()
}
C++ references differed from C# / Java references in that once you assign a value to it that was it, you couldn't re-assign it (and it has to be assigned when it was declared). This was the same as using a const pointer (a pointer that could not be re-pointed to another object).
C ++引用与C#/ Java引用的不同之处在于,一旦为其分配了值,就无法重新赋值(并且必须在声明它时分配它)。这与使用const指针(一个无法重新指向另一个对象的指针)相同。
Java and C# are very high level, modern languages which cleaned up a lot of the messes that had accumulated in C / C++ over the years and pointers was definitely one of those things that needed to be 'cleaned up'.
Java和C#是非常高级的现代语言,这些语言清理了多年来在C / C ++中积累的许多混乱,指针绝对是需要“清理”的东西之一。
As far as your comment about knowing pointers makes you a stronger programmer, this is true in most cases. If you know 'how' something works as opposed to just using it without knowing I would say this can often give you an edge. How much of an edge will always vary. After all, using something without knowing how it is implemented is one of the many beauties of OOP and Interfaces.
至于你对知识指针的评论使你成为一个更强大的程序员,在大多数情况下都是如此。如果你知道'怎么'有效,而不是仅仅使用它而不知道我会说这通常可以给你一个优势。边缘总是变化多少。毕竟,在不知道如何实现的情况下使用某些东西是OOP和接口的众多优点之一。
In this specific example, what would knowing about pointers help you with references? Understanding that a C# reference is NOT the object itself but points to the object is a very important concept.
在这个具体的例子中,了解指针有什么帮助你引用?理解C#引用不是对象本身,但指向对象是一个非常重要的概念。
#1: You are NOT passing by value Well for starters when you use a pointer you know that the pointer holds just an address, that's it. The variable itself is almost empty and that's why it's so nice to pass as arguments. In addition to the performance gain, you are working with the actual object so any changes you make are not temporary
#1:你没有通过值传递对于初学者来说,当你使用指针时,你知道指针只包含一个地址,就是这样。变量本身几乎是空的,这就是为什么传递参数这么好。除了性能提升之外,您还在使用实际对象,因此您所做的任何更改都不是临时的
#2: Polymorphism / Interfaces When you have a reference that is an interface type and it points to an object, you can only call methods of that interface even though the object may have many more abilities. The objects may also implement the same methods differently.
#2:多态/接口当你有一个接口类型的引用并且它指向一个对象时,你只能调用该接口的方法,即使该对象可能有更多的能力。对象也可以不同地实现相同的方法。
If you understand these concepts well then I don't think you are missing too much from not having used pointers. C++ is often used as a language for learning programming because it is good to get your hands dirty sometimes. Also, working with lower-level aspects makes you appreciate the comforts of a modern language. I started with C++ and am now a C# programmer and I do feel like working with raw pointers have helped me have a better understanding on what goes on under the hood.
如果你很好地理解这些概念,那么我认为你没有因为没有使用指针而错过太多。 C ++通常被用作学习编程的语言,因为有时候弄脏你的手很好。此外,使用较低级别的方面使您欣赏现代语言的舒适。我从C ++开始,现在是一名C#程序员,我觉得使用原始指针可以帮助我更好地了解幕后的内容。
I don't think it is necessary for everyone to start with pointers, but what is important is that they understand why references are used instead of value-types and the best way to understand that is to look at its ancestor, the pointer.
我不认为每个人都必须从指针开始,但重要的是他们理解为什么使用引用而不是值类型,理解它的最好方法是查看它的祖先,指针。
#1
C# references can, and will be relocated by garbage collector but normal pointers are static. This is why we use fixed
keyword when acquiring a pointer to an array element, to prevent it from getting moved.
C#引用可以并且将由垃圾收集器重定位,但是普通指针是静态的。这就是为什么我们在获取指向数组元素的指针时使用fixed关键字,以防止它被移动。
EDIT: Conceptually, yes. They are more or less the same.
编辑:从概念上讲,是的。它们或多或少相同。
#2
There is a slight, yet extremely important, distinction between a pointer and a reference. A pointer points to a place in memory while a reference points to an object in memory. Pointers are not "type safe" in the sense that you cannot guarantee the correctness of the memory they point at.
指针和引用之间存在轻微但非常重要的区别。指针指向内存中的某个位置,而引用指向内存中的对象。指针不是“类型安全”,因为您无法保证它们所指向的内存的正确性。
Take for example the following code
以下面的代码为例
int* p1 = GetAPointer();
This is type safe in the sense that GetAPointer must return a type compatible with int*. Yet there is still no guarantee that *p1 will actually point to an int. It could be a char, double or just a pointer into random memory.
从某种意义上说,这是类型安全的,GetAPointer必须返回与int *兼容的类型。然而,仍然无法保证* p1实际上会指向一个int。它可以是char,double或只是指向随机存储器的指针。
A reference however points to a specific object. Objects can be moved around in memory but the reference cannot be invalidated (unless you use unsafe code). References are much safer in this respect than pointers.
然而,引用指向特定对象。对象可以在内存中移动,但引用不能失效(除非您使用不安全的代码)。在这方面,参考文献比指针更安全。
string str = GetAString();
In this case str has one of two state 1) it points to no object and hence is null or 2) it points to a valid string. That's it. The CLR guarantees this to be the case. It cannot and will not for a pointer.
在这种情况下,str具有两种状态之一1)它指向没有对象,因此为空或2)它指向有效的字符串。而已。 CLR保证了这种情况。它不能也不会用于指针。
#3
A reference is an "abstract" pointer: you can't do arithmetic with a reference and you can't play any low-level tricks with its value.
引用是一个“抽象”指针:你不能用引用算术,你不能用它的值玩任何低级技巧。
#4
First I think you need to define a "Pointer" in your sematics. Do you mean the pointer you can create in unsafe code with fixed? Do you mean an IntPtr that you get from maybe a native call or Marshal.AllocHGlobal? Do you mean a GCHandle? The all are essentially the same thing - a representation of a memory address where something is stored - be it a class, a number, a struct, whatever. And for the record, they certainly can be on the heap.
首先,我认为你需要在你的sematics中定义一个“指针”。你的意思是你可以用固定的不安全代码创建指针吗?你的意思是你可能从本机电话或Marshal.AllocHGlobal得到的IntPtr?你的意思是GCHandle?所有这些都是基本相同的东西 - 存储内容的存储器地址的表示 - 无论是类,数字,结构还是其他。而且为了记录,他们当然可以在堆上。
A pointer (all of the above versions) is a fixed item. The GC has no idea what is at that address, and therefore has no ability to manage the memory or life of the object. That means you lose all of the benefits of a garbage collected system. You must manually manage the object memory and you have the potential for leaks.
指针(以上所有版本)都是固定项。 GC不知道该地址是什么,因此无法管理对象的内存或生命。这意味着您将失去垃圾收集系统的所有好处。您必须手动管理对象内存,否则可能会发生泄漏。
A reference on the other hand is pretty much a "managed pointer" that the GC knows about. It's still an address of an object, but now the GC knows details of the target, so it can move it around, do compactions, finalize, dispose and all of the other nice stuff a managed environment does.
另一方面,引用几乎是GC知道的“托管指针”。它仍然是一个对象的地址,但现在GC知道目标的细节,因此它可以移动它,进行压缩,最终化,处置以及托管环境所做的所有其他好东西。
The major difference, really, is in how and why you would use them. For a vast majority of cases in a managed language, you're going to use an object reference. Pointers become handy for doing interop and the rare need for really fast work.
实际上,主要区别在于您如何以及为何使用它们。对于托管语言中的绝大多数情况,您将使用对象引用。指针对于互操作以及对快速工作的罕见需求变得很方便。
Edit: In fact here's a good example of when you might use a "pointer" in managed code - in this case it's a GCHandle, but the exact same thing could have been done with AllocHGlobal or by using fixed on a byte array or struct. I tend to prefer the GCHandle becasue it feels more ".NET" to me.
编辑:事实上,这是一个很好的例子,说明何时可以在托管代码中使用“指针” - 在这种情况下它是一个GCHandle,但完全相同的事情可能是使用AllocHGlobal或使用固定的字节数组或结构。我倾向于选择GCHandle,因为它对我来说感觉更像“.NET”。
#5
Pointers point to a location in the memory address space. References point to a data structure. Data structures all moved all the time (well, not that often, but every now and then) by the garbage collector (for compacting memory space). Also, as you said, data structures without references will get garbage collected after a while.
指针指向内存地址空间中的位置。引用指向数据结构。数据结构都被垃圾收集器(用于压缩内存空间)一直移动(好吧,不是经常,但是时不时地)。另外,正如您所说,没有引用的数据结构将在一段时间后收集垃圾。
Also, pointers are only usable in unsafe context.
此外,指针仅在不安全的上下文中可用。
#6
I think it's important for developers to understand the concept of a pointer—that is, to understand indirection. That doesn't mean they necessarily have to use pointers. It's also important to understand that the concept of a reference differs from the concept of pointer, although only subtly, but that the implementation of a reference almost always is a pointer.
我认为对于开发人员来说理解指针的概念很重要 - 也就是了解间接性。这并不意味着他们必须使用指针。同样重要的是要理解引用的概念与指针的概念不同,尽管只是巧妙地,但是引用的实现几乎总是指针。
That is to say, a variable holding a reference is just a pointer-sized block of memory holding a pointer to the object. However, this variable cannot be used in the same way that a pointer variable can be used. In C# (and C, and C++, ...), a pointer can be indexed like an array, but a reference cannot. In C#, a reference is tracked by the garbage collector, a pointer cannot be. In C++, a pointer can be reassigned, a reference cannot. Syntactically and semantically, pointers and references are quite different, but mechanically, they're the same.
也就是说,保存引用的变量只是一个指针大小的内存块,其中包含指向该对象的指针。但是,此变量的使用方式与使用指针变量的方式不同。在C#(和C和C ++,...)中,指针可以像数组一样索引,但引用不能。在C#中,垃圾收集器跟踪引用,指针不能。在C ++中,指针可以重新分配,引用不能。在语法和语义上,指针和引用是完全不同的,但在机械上,它们是相同的。
#7
A pointer can point to any byte in the address space of the application. A reference is tightly constrained and controlled and managed by the .NET environment.
指针可以指向应用程序地址空间中的任何字节。 .NET环境严格限制和控制和管理引用。
#8
A major difference between a reference and a pointer is that a pointer is a collection of bits whose content only matters when it is actively being used as a pointer, while a reference encapsulates not only a set of bits, but also some metadata which keeps the underlying framework informed of its existence. If a pointer exists to some object in memory, and that object is deleted but the pointer is not erased, the pointer's continued existence won't cause any harm unless or until an attempt is made to access the memory to which it points. If no attempt is made to use the pointer, nothing will care about its existence. By contrast, reference-based frameworks like .NET or the JVM require that it always be possible for the system to identify every object reference in existence, and every object reference in existence must always either be null
or else identify an object of its proper type.
引用和指针之间的主要区别在于指针是位的集合,其内容仅在主动用作指针时才重要,而引用不仅封装了一组位,而且还封装了一些保留基础框架告知其存在。如果指针存在于内存中的某个对象,并且该对象被删除但指针未被擦除,则指针的继续存在不会造成任何伤害,除非或直到尝试访问它指向的内存。如果没有尝试使用指针,没有什么可以关心它的存在。相比之下,基于引用的框架(如.NET或JVM)要求系统始终可以识别存在的每个对象引用,并且现有的每个对象引用必须始终为null或者标识其正确类型的对象。
Note that each object reference actually encapsulates two kinds of information: (1) the field contents of the object it identifies, and (2) the set of other references to the same object. Although there isn't any mechanism by which the system can quickly identify all the references that exist to an object, the set of other references that exist to an object may often be the most important thing encapsulated by a reference (this is especially true when things of type Object
are used as things like lock tokens). Although the system keeps a few bits of data for each object for use in GetHashCode
, objects have no real identity beyond the set of references that exist to them. If X
holds the only extant reference to an object, replacing X
with a reference to a new object with the same field contents will have no identifiable effect except to change the bits returned by GetHashCode()
, and even that effect isn't guaranteed.
请注意,每个对象引用实际上都封装了两种信息:(1)它标识的对象的字段内容,以及(2)对同一对象的其他引用的集合。虽然系统没有任何机制可以快速识别对象存在的所有引用,但是对象存在的其他引用集通常可能是引用封装的最重要的东西(尤其是当类型为Object的东西用作锁定令牌之类的东西。尽管系统为每个对象保留了一些数据用于GetHashCode,但是对象除了存在于它们之外的引用集之外没有真正的标识。如果X保存对象的唯一现存引用,则使用相同字段内容替换对具有相同字段内容的新对象的X将没有可识别的效果,除非更改GetHashCode()返回的位,甚至不能保证该效果。
#9
The thing about pointers that makes them somewhat complex is not what they are, but what you can do with them. And when you have a pointer to a pointer to a pointer. That's when it really starts to get fun.
关于指针使它们有点复杂的事情不是它们的本质,而是你可以用它们做什么。当你有一个指向指针的指针时。那是真正开始变得有趣的时候。
#10
One of the biggest benefits of references over pointers is greater simplicity and readability. As always when you simplify something you make it easier to use but at the cost of flexibility and control you get with the low-level stuff (as other people have mentioned).
引用优于指针的最大好处之一是更高的简单性和可读性。与往常一样,当你简化某些东西时,你会更容易使用,但是以灵活性和控制为代价,你会得到低级别的东西(正如其他人提到的那样)。
Pointers are often criticized for being 'ugly'.
指针经常被批评为“丑陋”。
class* myClass = new class();
Now everytime you use it you have to dereference it first either by
现在,每次使用它时,您必须首先取消引用它
myClass->Method() or (*myClass).Method()
Despite losing some readability and adding complexity, people still needed to use pointers often as parameters so you could modify the actual object (instead of passing by value) and for the performance gain of not having to copy huge objects.
尽管失去了一些可读性并增加了复杂性,人们仍然需要经常使用指针作为参数,这样你就可以修改实际的对象(而不是通过值传递)以及不必复制大对象的性能提升。
To me this is why references were 'born' in the first place to provide the same benefit as pointers but without all that pointer syntax. Now you can pass the actual object (not just its value) AND you have a more readable, normal way of interacting with the object.
对我而言,这就是为什么引用首先是“天生的”,以提供与指针相同的好处,但没有所有指针语法。现在你可以传递实际的对象(而不仅仅是它的值)并且你有一个更可读,更正常的方式与对象交互。
MyMethod(&type parameter)
{
parameter.DoThis()
parameter.DoThat()
}
C++ references differed from C# / Java references in that once you assign a value to it that was it, you couldn't re-assign it (and it has to be assigned when it was declared). This was the same as using a const pointer (a pointer that could not be re-pointed to another object).
C ++引用与C#/ Java引用的不同之处在于,一旦为其分配了值,就无法重新赋值(并且必须在声明它时分配它)。这与使用const指针(一个无法重新指向另一个对象的指针)相同。
Java and C# are very high level, modern languages which cleaned up a lot of the messes that had accumulated in C / C++ over the years and pointers was definitely one of those things that needed to be 'cleaned up'.
Java和C#是非常高级的现代语言,这些语言清理了多年来在C / C ++中积累的许多混乱,指针绝对是需要“清理”的东西之一。
As far as your comment about knowing pointers makes you a stronger programmer, this is true in most cases. If you know 'how' something works as opposed to just using it without knowing I would say this can often give you an edge. How much of an edge will always vary. After all, using something without knowing how it is implemented is one of the many beauties of OOP and Interfaces.
至于你对知识指针的评论使你成为一个更强大的程序员,在大多数情况下都是如此。如果你知道'怎么'有效,而不是仅仅使用它而不知道我会说这通常可以给你一个优势。边缘总是变化多少。毕竟,在不知道如何实现的情况下使用某些东西是OOP和接口的众多优点之一。
In this specific example, what would knowing about pointers help you with references? Understanding that a C# reference is NOT the object itself but points to the object is a very important concept.
在这个具体的例子中,了解指针有什么帮助你引用?理解C#引用不是对象本身,但指向对象是一个非常重要的概念。
#1: You are NOT passing by value Well for starters when you use a pointer you know that the pointer holds just an address, that's it. The variable itself is almost empty and that's why it's so nice to pass as arguments. In addition to the performance gain, you are working with the actual object so any changes you make are not temporary
#1:你没有通过值传递对于初学者来说,当你使用指针时,你知道指针只包含一个地址,就是这样。变量本身几乎是空的,这就是为什么传递参数这么好。除了性能提升之外,您还在使用实际对象,因此您所做的任何更改都不是临时的
#2: Polymorphism / Interfaces When you have a reference that is an interface type and it points to an object, you can only call methods of that interface even though the object may have many more abilities. The objects may also implement the same methods differently.
#2:多态/接口当你有一个接口类型的引用并且它指向一个对象时,你只能调用该接口的方法,即使该对象可能有更多的能力。对象也可以不同地实现相同的方法。
If you understand these concepts well then I don't think you are missing too much from not having used pointers. C++ is often used as a language for learning programming because it is good to get your hands dirty sometimes. Also, working with lower-level aspects makes you appreciate the comforts of a modern language. I started with C++ and am now a C# programmer and I do feel like working with raw pointers have helped me have a better understanding on what goes on under the hood.
如果你很好地理解这些概念,那么我认为你没有因为没有使用指针而错过太多。 C ++通常被用作学习编程的语言,因为有时候弄脏你的手很好。此外,使用较低级别的方面使您欣赏现代语言的舒适。我从C ++开始,现在是一名C#程序员,我觉得使用原始指针可以帮助我更好地了解幕后的内容。
I don't think it is necessary for everyone to start with pointers, but what is important is that they understand why references are used instead of value-types and the best way to understand that is to look at its ancestor, the pointer.
我不认为每个人都必须从指针开始,但重要的是他们理解为什么使用引用而不是值类型,理解它的最好方法是查看它的祖先,指针。