局部变量或指针

时间:2011-09-28 08:27:39

标签: c++ pointers

在任何随机C ++框架中给出一个类,您如何知道是否必须在堆栈上创建一个简单对象或者指向堆上对象的指针?

假设一个函数以引用(&)变量的形式接受参数。调用者可以将局部变量传递给它或指针(* ptr)。被调用的函数可能会也可能不会从传递的对象中复制dat。

这个问题是我与{C ++ Bada开发相关的previous question的后续内容。

4 个答案:

答案 0 :(得分:6)

通常,每个精心设计的C ++库都允许这两者。在大多数情况下,库不关心调用者分配内存的位置,因为调用者处理自己的内存。如果库有额外的要求(例如,它占用了一个指针),那么它会仔细记录这个。

此外,作为一般准则,避免指针和freestore内存。 C ++在设计时考虑了堆栈对象。如果没有令人信服的理由使用不同的东西,那么就不要。 new应该只在你的代码中非常谨慎地使用,delete 永远不会使用 - 也就是说,总是让你的分配内存以自动方式处理(智能指针) )。

答案 1 :(得分:1)

如何创建对象取决于您打算如何处理。

如果使用new语句创建对象,则会获得指向手动分配的对象的指针。只要未使用delete手动解除分配,此对象就会生效。

如果在堆栈上创建一个简单对象,只要使用当前堆栈,也就是说只要范围不变,它就会保持不变。

诸如STL之类的公共库将允许两个对象。

如果库有特殊要求,必须在某处记录,并解释主要是因为它想要拥有该对象。

答案 2 :(得分:0)

没有“简单对象”这样的东西。对象是对象是对象。

重要的是对象生命周期:自动(范围),动态(手动)或静态(永久)。

尽可能多,除非你有其他非常好的理由,否则请使用具有自动生命周期的对象。

如果你考虑一个对象如何依赖另一个对象,你会发现如果你只使用自动对象,那么你就不会有悬空引用(或“引用局部变量”)的问题,因为依赖对象将具有比引用对象更深层嵌套的范围。

您应该有一个非常有说服力的论据,为什么特定对象必须具有手动生命周期。当然,这些情况会发生,但它们应该被抽象和消除。例如,大多数标准库容器当然需要手动管理其元素,但所有这些都由容器处理,以便用户可以只使用自动生命周期的容器对象,一切都很好。最后,如果您确定必须手动管理对象的生命周期,那么使用单一职责资源管理类(如shared_ptrunique_ptr)将句柄传递给该对象 - 处理程序类是现在再次自动,一旦超出范围,他们就会为您释放托管对象。您可以获得两全其美:手动对象分配范围职责的好处。

如果你有条不紊地遵循这些想法,你会发现自己很少会创建动态对象,如果你这样做,那么就会有一行相关的代码(这会给你“地方性”);例如,auto p = std::make_shared<T>(a,b,c);std::unique_ptr<T> p(new T(a,b,c));。所有源代码上grep的简单new都可以轻松审核是否负责任地处理所有动态分配。

答案 3 :(得分:0)

有很多事情需要考虑。在决定是否使用指针时,生命周期,对多态性,引用和性能的需求都是需要考虑的事情。

正如其他人所说,堆栈空间具有范围生命周期。一旦变量超出范围,就完成了。通过指针分配的内存将一直存在,直到调用delete为止,但请记住指针本身仍会超出范围!所以一定要在某个地方保留一个参考资料!

对于多态性,使用堆栈空间类型使得由于切片问题而无法实现。因此,如果你需要使用这种技术,请坚持使用指针。

参考文献应该是显而易见的。你需要将相同的内存移动到程序中的不同位置吗?有多少东西需要访问EXACT相同的内存,而不仅仅是副本吗?

最后,表现。使用堆内存会给你带来性能影响吗?由于需要额外的分配时间,因此指针速度较慢。它们还需要一些额外的内存来存储指针本身(实际上是微不足道的,但无论如何你也可以考虑它。真的取决于你的应用程序。)