何时使用指针而何时不使用?

我习惯于做Java编程,在编程时你永远不必考虑指针。 但是,目前我正在用C ++编写程序。 在创建具有其他类成员的类时,我应该何时使用指针,何时不应该使用指针? 例如,我什么时候想要这样做:

class Foo { Bar b; } 

与此相反:

 class Foo { Bar* b; } 

首先避免使用指针。

在以下情况下使

  • 你想使用Pimpl习语或抽象工厂 。
  • Bar实例实际上是由程序的其他部分管理的,而Foo类只需要能够访问它。
  • 你想推迟Bar对象的构造(即,你想构造Foo 之后创建它)。
  • 在您的业务逻辑中, Bar对象可能根本不存在; 你也会在Java中使用null 。 但是,请查看boost :: optional 。
  • Bar实际上是一个基类,你需要实例是多态的。
  • 您碰巧使用的工具包更喜欢将GUI小部件作为指针。 示例可以包括(但不限于) wxWidgets和GLUI 。

在任何这些情况下(*),首先使用智能指针,例如boost :: shared_ptr 。 否则,您可能迟早会忘记释放内存。 一旦你知道自己在做什么,就要考虑具体的指针类型。

(*)任何情况 – 除了可能是关于GUI小部件的子弹; 在这种情况下,您的工具包很可能也会为您管理资源

 class Foo { Bar b; } 

b 包含在Foo中。 如果Foo对象结束生命周期,b也会自动结束生命周期。 这是什么模型组成。 上面的b表示对象本身,而不是像Java中那样指向它的指针。 因此,如果b超出范围,该对象将终止生命周期。

 class Foo { Bar * b; } 

这里,对象b指向的对象 Foo对象使用 Foo对象引用 。 如果Foo对象结束生命周期,则对象b指向的可以继续生存,具体取决于具体情况。 这可以用于模拟聚合和一般关系。 例如,该对象可以与其他Foo对象共享。

指针大致是Java中的引用。 他们也可以指出一切。 如果指针指向什么,则它是空指针。

与指针类似的是引用。 必须初始化C ++中的引用,并且只能指向初始化引用的一个(有效)对象。 因此,对它的引用不能保持在Java中可能意味着“无”的null

在第一个示例中,在构造Foo对象时,将自动分配Bar对象的内存。 在第二种情况下,您需要自己分配内存。 所以你必须打电话:

 Foo *foo = new Foo(); foo->b = new Bar(); 

如果Bar对象很大并且您不想将其与Foo对象捆绑在一起,则可能需要这样做。 当Bar对象的构造独立于Foo对象的创建时,也是可取的。 在这种情况下,b对象被“注入”到foo中:

 Foo *foo = new Foo(); foo->b = b_ptr; 

其中b_ptr在其他地方构造,指针传递给foo。

对于较小的物体,这是危险的,因为您可能忘记分配内存。

在不同条件下两者都可以。 例如,如果您知道在构造类Foo的对象时如何构造b,则第一个是OK。 但如果你不这样做,唯一的选择是使用秒。

您需要进行一些汇编编程并很好地理解内存布局。 与Java或其他语言不同,C只是一个跨平台程序集。 要正确使用它,应该了解低级细节。

所有评论都是有效的,但是对于像你这样从高级语言跳到C语言的人来说,拥有这种经验将是非常有益的。 通过正确的理解,你不会再问这样的问题了。