【发布时间】:2010-09-28 16:14:09
【问题描述】:
我习惯于进行 Java 编程,在这种情况下,您在编程时不必真正考虑指针。但是,目前我正在用 C++ 编写程序。在创建具有其他类成员的类时,什么时候应该使用指针,什么时候不应该使用?例如,我什么时候想这样做:
class Foo {
Bar b;
}
与此相反:
class Foo {
Bar* b;
}
【问题讨论】:
我习惯于进行 Java 编程,在这种情况下,您在编程时不必真正考虑指针。但是,目前我正在用 C++ 编写程序。在创建具有其他类成员的类时,什么时候应该使用指针,什么时候不应该使用?例如,我什么时候想这样做:
class Foo {
Bar b;
}
与此相反:
class Foo {
Bar* b;
}
【问题讨论】:
从避免指针开始。
在以下情况下使用它们:
Bar 实例实际上由程序的其他部分管理,而 Foo 类只需要能够访问它。Bar 对象的构建(即,您希望在构建 Foo 之后创建它)。Bar 对象可能根本不存在;您也可以在 Java 中使用 null。不过,也请查看boost::optional。Bar其实是一个基类,需要实例是多态的。在任何这些情况 (*) 中,首先使用智能指针,例如 boost::shared_ptr。否则,您迟早可能会忘记释放内存。一旦你知道自己在做什么,请根据具体情况考虑哪种指针类型最好。
(*) 任何情况——可能除了关于 GUI 小部件的项目符号;在这种情况下,您的工具包很可能也会为您管理资源
【讨论】:
class Foo {
Bar b;
}
b 被 包含 在 Foo 中。如果 Foo 对象结束生命周期, b 也会自动结束生命周期。这就是模型组合。上面的 b 表示对象本身,而不仅仅是像 Java 中那样指向它的指针。因此,如果 b 超出范围,对象将结束生命周期。
class Foo {
Bar * b;
}
这里,b 指向的对象是被 使用或被 Foo 对象引用。如果 Foo 对象结束生命周期,则 b 指向的对象可能会继续存在,具体取决于情况。这可用于对聚合和一般关系进行建模。例如,该对象可以与其他 Foo 对象共享。
指针大致就是 Java 中的引用。他们也可以什么都没有。如果指针不指向任何内容,则它是空指针。
与指针类似的是引用。 C++ 中的引用必须被初始化并且只能指向一个(有效的)对象,该对象的引用被初始化。因此,引用不能保持价值,这可能意味着像 Java 中的 null 这样的“无”。
【讨论】:
Foo 对象结束生命周期,b 也会自动结束生命周期。”而不是Bar 代替Foo。
在第一个示例中,Bar 对象的内存将在您构造 Foo 对象时自动分配。在第二种情况下,您需要自己分配内存。所以你必须打电话:
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。
对于较小的对象,这是很危险的,因为您可能会忘记分配内存。
【讨论】:
new 返回一个指针,而不是一个值。你是说Foo foo吗?或 Foo foo = Foo();代替?
在不同的条件下两者都可以。例如,如果在构造 Foo 类的对象时知道如何构造 b,那么第一个就可以了。但如果你不这样做,唯一的选择就是使用第二个。
【讨论】:
你需要做一些汇编编程并很好地理解内存布局。 C 只是一个跨平台程序集,与 Java 或其他语言不同。要正确使用它,应该了解底层细节。
制作的所有 cmet 都是有效的,但是对于像您这样从高级语言跳到 C 语言的人来说,拥有这种经验将是有益的。有了正确的理解,你就不会再问这样的问题了。
【讨论】: