在C ++ 11后的现代C ++中使用原始指针

鉴于C ++ 11标准现在得到了大多数体面编译器的良好支持,2014年使用原始指针的主要原因有哪些?

我确定了几个场景:

  1. 您正在扩展大量使用原始指针的遗留代码库,并且您希望保持样式的一致性。

  2. 您正在使用仅导出原始指针的库,但我猜您仍然可以使用强制转换。

  3. 您希望利用指针的function来提供多个级别的间接。 (我不太清楚C ++ 11是否足以知道是否可以使用智能指针或使用其他技术来实现。)

您认为哪些其他场景适合使用指针?

今天你甚至会建议学习一般的指针吗?

我可以想象你有一个静态分配数组的情况,并且你想使用原始指针在高性能代码中迭代它。 这还没什么不对。

你的#1是真的。

你的#2可能不对:如果你是“利用强制转换”来将第三方库所拥有的原始指针转换为智能指针(暗示本地所有权),那么就会出现严重错误。

你的#3在技术上是正确的,但你可以随时避免这种情况。

现在建议使用原始指针指向您自己的动态分配内存 。 也就是说,建议是在没有智能指针的情况下避免new (并且推论是你不应该delete )。

每个人都反对原始指针,因为它太容易泄漏它们。

但是你可以使用原始指针指向其他地方拥有的数据……只是不要new / delete它们。 使用std::unique_ptrstd::shared_ptr 。 或者对于哑(POD)内存缓冲区使用std::vector ,不要mallocfree自己。

想象一下std::vector当你需要处理那些不容易复制但已经存在于别处的对象的子选择时。 你需要指针。

您还需要函数中的指针用于可选参数,其中引用不会将其剪切,因为您希望能够传递nullptr

连续对象的指针也可以轻松迭代, 不需要任何std::iterator开销 。 只是++--就是这样。 我经常使用直接指针迭代而不是beginend向量。

当你了解它们是如何工作的时候……你需要它们很多,你会正确地使用它们。

智能指针用于处理对象所有权问题,但并非所有指针都用于处理对象所有权。 例如,如果您不打算将所有权传递给此函数,则将原始指针传递给函数会更有意义(即您只是希望函数处理指针所寻址的数据)

恕我直言原始指针仍然有他们的位置。

C ++ 11给我们的是能够管理原始指针的生命周期,这样我们就不必自己删除它们了。

使用原始指针没有任何问题,只要它们由正确范围或框架中的智能指针/指针管理器管理,以确保它们的寿命是正确的。 如果确实如此,那么您永远不必删除原始指针,并且可以在范围/框架内安全地使用它们,在此范围内保证其生命周期。

我会说,如果可能的话,如果它的生命周期应该由给定的范围/帧控制,则在std::unique_ptr存储一个指向新对象的原始指针。 完成后,使用该范围框架内的原始指针。 永远不要删除它;

有时,无法从单个范围或框架管理新对象的生命周期。 在这种情况下,在每个范围/框架中使用std::shared_ptr ,它们独立地需要管理新对象的生命周期。 然后,在每个范围/帧内,没有理由不使用原始指针,就像它由std::unique_ptr管理一样。

因此,通常没有理由引起智能指针的速度劣势,因为它们的优势之一在于管理新对象的寿命,以确保原始指针的有效性和其对象的自动销毁。不再需要。

还有一些时候原始指针不合适。

例如,当托管指针需要将“所有权”转移到另一个范围/框架时。 那时您需要负责管理要更改的新对象的生命周期的范围/框架。 在这些情况下, 避免像瘟疫一样的原始指针!

您认为哪些其他场景适合使用指针?

使用原始指针的主要方案之一是当您拥有非拥有指针时。 通常,引用可以使用,但您希望避免引用的约束(不可重定位,不可复制)。 在这些情况下,您可以使用reference_wrapper类型,但只使用原始指针更简单。 智能指针编码所有权(谁创建和销毁对象),因此,如果没有编码所有权(因为它是隐含的),那么原始指针就可以了。

为了说清楚,我刚才解释的典型例子是:

  • 临时可复制仿函数,需要指向它不拥有的某个对象的指针。
  • 数据结构内的内部交叉链接(例如,“后向指针”)。

但重要的是要注意,这些东西通常不应出现在接口中。 通常,您可以在接口(例如,库函数和类)中完全避免原始指针,并且只在内部使用它们,即在库侧代码中,而不是在用户端代码中。 换句话说,如果您需要使用原始指针,请将它们隐藏起来。

对于可选的函数参数,有时也会看到原始指针,如果不需要该结果,则可以传入nullptr

应该避免的主要问题是,通常可以避免的是用户端代码中的裸new / delete调用。 一个典型的好的现代C ++库(对于C ++ 11更是如此)将不会有任何这样的裸new / delete事件,这是事实。

原始指针本身并不是一个问题,有问题的是(1)手动内存管理,以及(2)所有权管理(如果使用原始指针而不是智能指针则会出现问题)。

今天你甚至会建议学习一般的指针吗?

当然你应该学习指针。 它们对于理解编程和学习编写库侧代码至关重要。 即使你没有看到它们,原始指针仍然存在于许多库代码的内容中。

使用原始指针的常见原因。

  1. 读取和解析二进制文件
  2. 直接与硬件交互
  3. arrays?
  4. 速度。 AFAIK智能指针比原始指针慢,并且有相对安全的方法来使用原始指针。 例如,请参阅Chromium的代码库或WebKit。 两者都使用各种跟踪内存而没有智能指针的全部开销。 当然也有局限性。