如果我需要将重的东西传递给对象,我应该通过指针还是通过副本传递

If I need to pass in something heavy to an object, should I just pass in by pointer or by copy?

本文关键字:我应该 指针 副本 对象 如果      更新时间:2023-10-16

我有一个C++对象(Vision.cpp),它在构造函数中获取了一堆图像。对象对这些图像执行一些图像处理并返回结果。这种情况发生在服务器端。图像由客户端拍摄并发送到服务器,如下所示:

客户端获取图像-->服务器接收图像-->服务器实例化Vision.cpp并按图像序列传递

正如预期的那样,图像序列的内存很重。我应该设计Vision.cpp类来复制图像,还是应该只保留指向图像的指针,并强制服务器在Vision.cpp完成处理之前不释放为图像分配的内存?我想复制以避免强制服务器保持其指针有效,但图像复制也需要时间。有什么好的解决方案吗?

在这些情况下,我通常使用其中一种:

  • 不可变数据(如果重用/共享输入图像,则效果良好)。这可以是一个参考,也可能是std::shared_ptr<const Image>。对于渲染管道,您也可以使用目标缓冲区(例如渲染目标),那么Vision只是一个处理器的集合,不拥有任何输入或输出图像。因此,这里的一个场景是,您有一堆输入图像——服务器为所有创建的Vision提供了对图像的不可变引用。然后RenderDestination会要求Vision渲染到RenderDestination的位图。如果重用图像,这通常是一个胜利。这可能会导致渲染期间的复制(排序),但如果重用目标,则可以减少分配。

  • 或者,您可以转移位图的所有权,并使用过程就地表单,将(可变)位图表示从一个处理器传递到下一个处理器,直到处理完成。如果不重复使用图像,这通常是一种胜利,但如果输入图像被重复使用,服务器生成/复制/重新打开这些图像的成本可能会很高。

但有几种方法可以解决这个问题——这取决于你如何使用输入和处理。

使用引用或指针,并确保图像的生存期超过处理的持续时间。除非Vision对象需要在处理调用之后保留对图像数据的访问,否则这应该相对简单。制作所有这些副本对你的表现来说都很糟糕(而且副本会比你意识到的更多)。您需要习惯于仔细考虑C++中的对象所有权和生存期,因为会有更多的问题根本无法处理副本。