【发布时间】:2012-12-04 23:09:31
【问题描述】:
我经常使用 OpenCV C++ 接口并设计了许多使用 Mat 作为私有资源的类。
最近,我开始关注 Mat 类,因为它总是使用图像数据作为共享资源,除非我明确调用 clone。 即使我写了const Mat,我也不能确定以后不会从外部更改图像数据。
所以我需要克隆以确保封装。但是需要显式克隆一个 Mat 的问题是它通常是不必要且昂贵的。另一方面,我知道对共享图像数据的需求源于 roi 选择器,并且能够编写如下内容:
Mat m_small = m_big(my_roi).
我的问题是:
1.) 不应该懒惰地克隆 cv::Mat 类吗? 这样用户就不会从外部将 Mat 视为共享资源处理程序。当需要真正的共享图像数据时,用户不应该显式实例化一个名为 SharedMat 的类吗?
2.) 在将 cv::Mat 作为类的私有资源的情况下,您是否有任何比总是克隆更好的策略?
更新:“除非您打算修改数据,否则不要使用Mat::clone()。” (作者 Vadim Pisarevsky)
这个想法有问题。
考虑一下你有这个类的情况:
class Res_handler{
public:
const Mat emit_mat(){ return m_treasure; } // I argue you are compelled to clone here.
private:
Mat m_treasure;
};
如果你不clone在这种情况下你可以写
Mat m_pirate = res_handler.emit_mat(); m_pirate = Scalar(0,0,0);
通过m_pirate 和m_treasure 之间共享的图像数据导致res_handler 内部的m_treasure 完全停电。 :) 所以为了避免意外修改内部m_treasure,你需要clone它。
另一方面,这个解决方案也有缺陷:
const Mat m_pirate = res_handler.emit_mat();
因为m_treasure也可以被修改,所以m_pirate的内容在后台被修改了,让盗版的程序员很头疼。 :)
【问题讨论】: