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

时间:2008-12-29 07:04:48

标签: java c++ pointers

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

class Foo {
    Bar b;
}

与此相反:

class Foo {
    Bar* b;
}

5 个答案:

答案 0 :(得分:39)

首先避免使用指针。

在以下时间使用它们:

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

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

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

答案 1 :(得分:19)

class Foo {
    Bar b;
}

b在Foo中包含。如果Foo对象结束生命周期,b也会自动结束生命周期。这就是模特的构图。上面的b表示对象本身,而不仅仅是Java中的指针。因此,如果b超出范围,该对象将终止生命周期。

class Foo {
    Bar * b;
}

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

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

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

答案 2 :(得分:3)

在第一个示例中,在构造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。

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

答案 3 :(得分:1)

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

答案 4 :(得分:1)

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

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