1

我正在阅读 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.如何在按值传递时指向同一个内存块?我觉得这与=运算符重载有关。但是它说即使返回了图像,它也只会返回指向同一内存块的图像,而不会创建新的图像。我不明白他们是如何实现这一点的。

但这是我所理解的:

鉴于按值传递并返回图像使新图像共享相同的内存块,因此实现引用计数是有意义的。

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

4

4 回答 4

2

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

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

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

于 2013-07-11T06:19:11.297 回答
1

Multiple cv::Mats can share the same data array but have different header. There is a counter that counts how many mats are using this data array. When the counter reacher 0, the data array is freed. Or it will exist all the time. Besides, CvMat、<code>Mat and IplImage can share the same data array without problem. The only difference between them is header.

于 2013-07-11T06:22:43.140 回答
1

当按值传递时,如何指向同一个内存块?

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

于 2013-07-11T06:37:47.273 回答
1

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

于 2013-07-11T06:17:56.173 回答