Я много работаю с интерфейсом OpenCV С++ и разработал ряд классов, которые используют Mat как частные ресурсы.
В последнее время меня беспокоил класс Mat, поскольку он всегда использует данные изображения в качестве общего ресурса, если я явно не вызываю clone. Даже если я пишу const Mat, я не могу быть уверен, что imagedata не будет изменяться позже извне.
Поэтому мне нужно клонировать, чтобы обеспечить инкапсуляцию. Но проблема с необходимостью явного клонирования Mat заключается в том, что он часто бывает ненужным и дорогостоящим. С другой стороны, я понимаю, что потребность в общих изображениях возникает из селекторов roi и может написать что-то вроде этого:
Mat m_small = m_big(my_roi).
Мои вопросы:
1.) Разве класс cv:: Mat не будет клонирован лениво?. Таким образом, пользователь не увидит Mat как общие обработчики ресурсов извне. Должен ли пользователь явно создавать экземпляр класса, называемого как SharedMat, когда требуется реальная общая информация?
2.) У вас есть стратегия лучше, чем всегда клонирование в случае cv:: Mat как частный ресурс для класса?
UPDATE: "вы не используете Mat::clone(), если вы не планируете изменять данные". (Вадим Писаревский)
У этой идеи есть проблема.
Рассмотрим ситуацию, когда у вас есть этот класс:
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_treasure внутри res_handler через данные общего изображения между m_pirate и m_treasure.:) Поэтому, чтобы избежать случайной модификации внутреннего m_treasure, вам нужно clone его.
С другой стороны, это решение также ошибочно:
const Mat m_pirate = res_handler.emit_mat();
потому что m_treasure тоже может быть изменен, поэтому содержимое m_pirate изменяется в фоновом режиме, вызывая сильную головную боль для пиратского программиста.:)