何时使用指针,何时不使用指针

15

我目前正在进行我的第一个真正的C++项目,所以对指针还比较陌生。我知道它们是什么,并阅读了一些基本用法规则。但很可能不够,因为我仍然不真正理解何时使用它们,何时不使用。

问题在于大多数地方都只提到大多数人过度使用它们或未充分利用它们。我的问题是,何时使用它们,何时不使用?

目前,在许多情况下,我在问自己,我应该在这里使用指针还是只传递变量本身到函数中。

例如,我知道您可以将指针发送到函数中,以便函数可以实际更改变量本身而不是其副本。但是当您只需要一次获取对象的某些信息(例如方法需要一个getValue())时,在那种情况下使用指针是否有用呢?

我希望看到反应,也希望看到可能有用的链接。由于这是我第一次使用C++,因此我还没有一本好的C++书(如果我继续使用C ++,我想买一本)。


6
一本书是绝对必要的(实际上不止一本),你不能单凭SO的答案学会C++。而且推荐读的这本书是Koenig & Moo的《Accelerated C++》。 - anon
今天早些时候,我在阅读https://dev59.com/_3RC5IYBdhLWcg3wK9yV后,就预测到了这一点:D - bastijn
9个回答

21

关于C++的做与不做:

Scott Meyers 的《Effective C++》和《More Effective C++》。

关于指针(和引用):

  • 如果类型适合4字节并且不希望在调用返回后更改,请使用按值传递。
  • 如果类型较大并且不希望在调用返回后更改,请使用按const引用传递。
  • 如果参数不能为NULL,请使用按引用传递。
  • 否则,请使用指针。

如果不需要,请不要使用裸指针。大多数情况下,智能指针(见 Boost)是更好的选择。


1
64位架构中的那4个字节是什么意思? - sbi
对于第一条规则,我会建议“使用按值传递,如果 sizeof(T) > sizeof(int)…” - Evan Teran
关于较大类型的传递引用问题,http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/ 值得一读。 - jalf
@Evan:我的意思是,像所有魔数一样,“4”是任意的,因此不好。据我所知,在IA64上,“sizeof(int)”也不好,因为那里的“int”是32位的。(别让我开始发牢骚了……)而且我记得很久以前在c.l.c++.m上有人提到过一个C++编译器,无论大小如何,都不会通过值传递结构体。总之,我的观点是:“4”(和“sizeof(int)”)对于“常见的32位架构上的常见编译器”可能是可以接受的。 - sbi
当然,4作为一个神奇的数字是“不好”的。我使用它是因为它更容易记住,并且大部分开发仍然是32位的。把它看作是一个提示,去了解类型的大小以及它如何编译。一旦你理解了编译器的工作原理,你就会真正明白在什么情况下使用什么。 - Tobias Langner
1
@sbi:关于 sizeof(int) 的问题,也许 sizeof(long) 是一个更好的度量标准,因为在 64 位系统上它会更大。我的观点是不要硬编码它,而是基于该架构/编译器的本机类型。 - Evan Teran

8

4

1)我倾向于使用类作用域的成员变量。它们在类的初始化器中构造,我不需要担心指针问题。

2)您可以通过引用传递给函数,而无需担心传递指针。这将有效地传递一个指向方法/函数的指针,可以像传递类一样使用,但不会复制类本身的开销。

3)如果我需要控制独立于我的主应用程序架构类的对象的生命周期...那么我将使用STL中的auto_ptr,在不再引用它时自动处理指针的销毁。试试吧 - 这是正确的方式。


2

每当你处理已分配的内存或将参数通过引用传递给方法时,请使用指针;我认为没有不使用指针的规则。


这是C++,所以你可能更倾向于使用引用而不是指针。 - frankster

2

我的经验法则:

  1. 始终将函数参数作为const引用传递,
  2. 除非它们是内置类型,在这种情况下会被复制(而const /非const成为风格问题,因为调用者不会受到影响),或
  3. 除非它们在函数内部被更改,以便更改反映在调用者处,此时它们被传递为非const引用,或者
  4. 除非即使调用者没有要传递的对象也应该能够调用函数,然后它们被传递为指针,以便调用者可以传递NULL指针(根据#1和#3决定是否按照const T*T*传递)

流必须始终作为非const引用传递。


0

通常情况下,如果可以使用引用而不是指针,这是一个好主意。引用必须有一个目标(没有空指针违规),当作为函数参数传递时,它们允许与指针相同的语义,并且对于初学者(或那些不来自C背景的人)来说,它们通常更易于使用。

当您想要进行动态内存分配时,需要使用指针;当您需要处理稍后将被指定的未知数量的事物时。在这种情况下,访问内存的接口是通过newdelete处理指针。


0

我的哲学是始终按值传递,除非你需要修改传递的变量或复制对象很昂贵。在这两种情况下,考虑首先使用引用而不是指针:如果你不需要更改所引用的对象,也不需要可能的极端值(NULL指针),那么可以使用引用。

别忘了迭代器。


0
以上都是不错的答案。另外,如果你正在执行一些处理器密集的工作,重要的是要意识到解引用指针可能会在处理器上导致缓存未命中。最好的做法是尽量减少指针解引用来保持数据的访问性。

0
  1. 类属性:指针
  2. 方法中声明的变量:没有指针,因此我们避免了内存泄漏。

通过这种方式,可以防止内存泄漏并控制属性的一致性。

祝好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接