如何通过引用返回对象是可能的

How is returning an object by reference possible?

本文关键字:对象 何通过 引用 返回      更新时间:2023-10-16

我正在阅读OpenCV教程,其中介绍了以下关于OpenCV的图像持有者类(cv::Mat)的内容:

The cv::Mat class implements reference counting and shallow copy such that when an image 
is assigned to another one, the image data (that is the pixels) is not copied, and both images 
will point to the same memory block. This also applies to images passed by value or returned 
by value. A reference count is kept such that the memory will be released only when all of the 
references to the image will be destructed. 

我特别感兴趣的是说This also applies to images passed by value or returned.的部分。当通过值传递时,如何可能指向同一个内存块?我觉得这与重载=运算符有关。但它表示,即使返回了一个图像,它也只返回一个指向同一内存块的图像,而不会创建新的内存块。我不明白他们是怎么做到的。

但我的理解是:

假设传递值和返回图像使新图像共享相同的内存块,那么实现参考计数是有意义的。

但是,您能解释一下内存块是如何共享的吗?即使对象是按值返回或传递的?

这相对容易:在类的构造函数中,您可以分配内存,例如使用new。如果你复制一个对象,你不会每次都分配新的内存,而是只复制指向原始内存块的指针,同时增加一个也存储在内存中的引用计数器,这样对象的每个副本都可以访问它。销毁对象将减少引用计数,并且只有在引用计数降至零时才释放分配的内存。

您只需要一个自定义的复制构造函数和赋值运算符。

这基本上就是共享指针的工作方式。

它可以像cv::Mat一样简单,它有一个指向动态分配的内存块的共享指针。复制Mat实例时,复制的是共享指针(增加引用计数),而不是它所指向的资源。

多个cv::Mat可以共享相同的数据数组,但具有不同的标头。有一个计数器可以统计有多少垫子正在使用此数据阵列。当计数器到达0时,数据数组被释放。或者它将一直存在。此外,CvMatMatIplImage可以毫无问题地共享同一数据阵列。它们之间唯一的区别是头。

传递时如何指向同一内存块按价值?

cv::Mat结构实际上管理一个动态分配的内存位置。它只是充当一个指向该位置的指针,并携带有关矩阵属性的信息。当您通过值传递这个变量时,您只复制这个指针,动态内存不会被复制。为了深入复制cv::Mat的所有元素,有一种方法叫做copyTo()。