Ist die cv :: Mat-Klasse vom Design her fehlerhaft?
Ich arbeite viel mit der OpenCV C ++ Schnittstelle und habe eine Reihe von Klassen entworfen, die Mat's als private Ressourcen verwenden.
Kürzlich machte ich mir Sorgen um die Mat-Klasse, da sie immer Bilddaten als gemeinsam genutzte Ressource verwendet, es sei denn, ich rufe ausdrücklich clone auf.Auch wenn ich schreibeconst Mat
Ich kann nicht sicher sein, dass die Bilddaten später von außen nicht verändert werden.
Ich muss also klonen, um die Kapselung sicherzustellen. Das Problem beim expliziten Klonen einer Matte ist jedoch, dass sie häufig unnötig und teuer ist. Andererseits verstehe ich, dass das Bedürfnis nach freigegebenen Bilddaten von Roi-Selektoren herrührt und in der Lage ist, so etwas zu schreiben:Mat m_small = m_big(my_roi)
.
Meine Fragen sind:
1.)Sollte die cv :: Mat-Klasse nicht eher träge geklont werden? Der Benutzer sieht Mat's daher nicht als freigegebene Ressourcen-Handler von außen. Sollte der Benutzer nicht explizit eine Klasse namens so etwas instanziierenSharedMat
Wann werden echte freigegebene Bilddaten benötigt?
2.) Hast du welche?Bessere Strategie als immer klonen im Falle von cv :: Mat als private Ressource für eine Klasse?
UPDATE: "Sie verwenden nichtMat::clone()
es sei denn, Sie planen, die Daten zu ändern. "(von Vadim Pisarevsky)
Diese Idee hat ein Problem. Betrachten Sie die Situation, in der Sie diese Klasse haben:
class Res_handler{
public:
const Mat emit_mat(){ return m_treasure; } // I argue you are compelled to clone here.
private:
Mat m_treasure;
};
Wenn Sie nichtclone
In diesem Fall können Sie schreiben
Mat m_pirate = res_handler.emit_mat(); m_pirate = Scalar(0,0,0);
Dies führt zu einem vollständigen Stromausfall in derm_treasure
in derres_handler
durch die gemeinsamen Bilddaten zwischenm_pirate
undm_treasure
. :) So vermeiden Sie versehentliche Veränderungen des Innerenm_treasure
, du musstclone
es.
Andererseits ist diese Lösung auch fehlerhaft:
const Mat m_pirate = res_handler.emit_mat();
dam_treasure
kann auch geändert werden, so dass der Inhalt vonm_pirate
wird im Hintergrund verändert, was dem Programmierer des Piraten große Kopfschmerzen bereitet. :)