【问题标题】:Local variable or a pointer局部变量或指针
【发布时间】:2011-11-26 16:16:07
【问题描述】:

给定一个任意 C++ 框架中的类,你怎么知道你是必须在堆栈上创建一个简单的对象还是在堆上创建一个指向对象的指针?

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

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

【问题讨论】:

  • 好问题!在 C++ 中,我通常非常害怕堆栈对象。您需要牢记堆栈的生命周期。但我正在等待真正知道答案的人。 :)
  • @Amigable 那你可能做错了什么。 C++ 喜欢堆栈对象。你不应该害怕他们。
  • @Konrad Rudolph,我可能是,但我是来学习的! :)

标签: c++ pointers


【解决方案1】:

一般来说,每个设计良好的 C++ 库都允许两者兼有。在大多数情况下,库不关心调用者在哪里分配内存,因为调用者处理自己的内存。如果库有其他要求(例如,它接管了指针的所有权),那么它将仔细记录这一点。

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

【讨论】:

  • 除了必须在智能指针中使用delete,对吧? :)
  • @Amigable 是的,但这不再是您的责任。在你的代码中有delete 是一个非常确定的代码异味标志,除非你碰巧实现了一个智能指针(或垃圾收集器)库。在所有其他情况下,它都放错了位置。
【解决方案2】:

如何创建对象取决于您打算做什么。

如果您使用new 语句创建一个对象,您将获得一个指向手动分配对象的指针。只要不使用 delete 手动释放此对象,它就会一直存在。

如果你在堆栈上创建一个简单的对象,只要当前堆栈被使用,它就会一直存在,也就是说只要范围没有改变。

STL 等公共库将允许这两个对象。

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

【讨论】:

    【解决方案3】:

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

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

    尽可能多地使用具有自动生命周期的对象,除非您有非常非常好的理由不这样做。

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

    您应该有一个非常有说服力的论据,为什么特定对象必须具有手动生命周期。这些情况当然会发生,但应该将它们抽象出来并分解掉。例如,大多数标准库容器当然需要对其元素进行手动管理,但所有这些都由容器处理,因此用户只需使用自动生命周期的容器对象就可以了。最后,如果你决定你真的必须手动管理一个对象的生命周期,那么使用像shared_ptrunique_ptr这样的单一职责资源管理类来传递一个句柄给那个对象——处理程序类现在又是自动的了,一旦它们超出范围,它们就会为您释放托管对象。您将获得两全其美:手动对象分配的好处范围责任。

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

    【讨论】:

      【解决方案4】:

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

      正如其他人所说,堆栈空间具有范围生命周期。一旦变量超出范围,它就完成了。通过指针分配的内存将持续存在,直到对其调用 delete 为止,但请记住,指针本身仍然会超出范围!因此,请务必在某处保留参考!

      至于多态性,由于切片问题,使用堆栈空间使之成为不可能。因此,如果您需要使用这种技术,请坚持使用指针。

      引用应该是显而易见的。您是否需要将相同的内存移动到程序中的各个位置?是否有多个事物需要访问完全相同的内存,而不仅仅是一个副本?

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

      【讨论】:

        猜你喜欢
        • 2021-11-11
        • 2017-11-23
        • 2014-05-18
        • 2013-10-03
        • 1970-01-01
        • 2014-05-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多