1 | initial version |
I found that the Template ownership and lifetime issues get quite complicated. At the heart of the problem is the ChamferMatcher::Template::rescale function, which can either return "this" or a new-allocated Template object. A template can also hold scaled templates in an internal vector. Template pointers can also be copied to Matching, etc.
If one is willing to use the modern C++11 standard library, the problems can be resolved with std::shared_ptr, which does reference counting and only destroys an object when the last pointer to it is destroyed.
std::shared_ptr<ChamferMatcher::Template> ChamferMatcher::Template::rescale(float new_scale)
{
if (fabs(scale - new_scale) < 1e-6) return shared_from_this();
for (size_t i=0;i<scaled_templates.size();++i) {
if (fabs(scaled_templates[i]->scale-new_scale)<1e-6) {
return scaled_templates[i];
}
}
float scale_factor = new_scale/scale;
auto tpl = std::make_shared<Template>();
tpl->scale = new_scale;
tpl->center.x = int(center.x*scale_factor+0.5);
tpl->center.y = int(center.y*scale_factor+0.5);
tpl->size.width = int(size.width*scale_factor+0.5);
tpl->size.height = int(size.height*scale_factor+0.5);
tpl->coords.resize(coords.size());
tpl->orientations.resize(orientations.size());
for (size_t i=0;i<coords.size();++i) {
tpl->coords[i].first = int(coords[i].first*scale_factor+0.5);
tpl->coords[i].second = int(coords[i].second*scale_factor+0.5);
tpl->orientations[i] = orientations[i];
}
scaled_templates.push_back(tpl);
return tpl;
}
All uses of Template* should be replaced with std::shared_ptr<template> and all uses of const Template * with std::shared_ptr<const template="">. Then all the raw delete operations are not necessary, and the matches can be used safely.
2 | No.2 Revision |
I found that the Template ownership and lifetime issues get quite complicated. At the heart of the problem is the ChamferMatcher::Template::rescale function, which can either return "this" or a new-allocated Template object. A template can also hold scaled templates in an internal vector. Template pointers can also be copied to Matching, etc.
If one is willing to use the modern C++11 standard library, the problems can be resolved with std::shared_ptr, which does reference counting and only destroys an object when the last pointer to it is destroyed.
std::shared_ptr<ChamferMatcher::Template> ChamferMatcher::Template::rescale(float new_scale)
{
if (fabs(scale - new_scale) < 1e-6) return shared_from_this();
for (size_t i=0;i<scaled_templates.size();++i) {
if (fabs(scaled_templates[i]->scale-new_scale)<1e-6) {
return scaled_templates[i];
}
}
float scale_factor = new_scale/scale;
auto tpl = std::make_shared<Template>();
tpl->scale = new_scale;
tpl->center.x = int(center.x*scale_factor+0.5);
tpl->center.y = int(center.y*scale_factor+0.5);
tpl->size.width = int(size.width*scale_factor+0.5);
tpl->size.height = int(size.height*scale_factor+0.5);
tpl->coords.resize(coords.size());
tpl->orientations.resize(orientations.size());
for (size_t i=0;i<coords.size();++i) {
tpl->coords[i].first = int(coords[i].first*scale_factor+0.5);
tpl->coords[i].second = int(coords[i].second*scale_factor+0.5);
tpl->orientations[i] = orientations[i];
}
scaled_templates.push_back(tpl);
return tpl;
}
All uses of Template* should be replaced with std::shared_ptr<template> std::shared_ptr<Template>
and all uses of const Template * with std::shared_ptr<const template="">. std::shared_ptr< const Template >
. Then all the raw delete operations are not necessary, and the matches can be used safely.
3 | No.3 Revision |
I found that the Template ownership and lifetime issues get quite complicated. At the heart of the problem is the ChamferMatcher::Template::rescale function, which can either return "this" or a new-allocated Template object. A template can also hold scaled templates in an internal vector. Template pointers can also be copied to Matching, etc.
If one is willing to use the modern C++11 standard library, the problems can be resolved with std::shared_ptr, which does reference counting and only destroys an object when the last pointer to it is destroyed.
std::shared_ptr<ChamferMatcher::Template> ChamferMatcher::Template::rescale(float new_scale)
{
{
if (fabs(scale - new_scale) < 1e-6) return shared_from_this();
for (size_t i=0;i<scaled_templates.size();++i) {
if (fabs(scaled_templates[i]->scale-new_scale)<1e-6) {
return scaled_templates[i];
}
}
float scale_factor = new_scale/scale;
auto tpl = std::make_shared<Template>();
tpl->scale = new_scale;
tpl->center.x = int(center.x*scale_factor+0.5);
tpl->center.y = int(center.y*scale_factor+0.5);
tpl->size.width = int(size.width*scale_factor+0.5);
tpl->size.height = int(size.height*scale_factor+0.5);
tpl->coords.resize(coords.size());
tpl->orientations.resize(orientations.size());
for (size_t i=0;i<coords.size();++i) {
tpl->coords[i].first = int(coords[i].first*scale_factor+0.5);
tpl->coords[i].second = int(coords[i].second*scale_factor+0.5);
tpl->orientations[i] = orientations[i];
}
scaled_templates.push_back(tpl);
return tpl;
}
}
All uses of Template* should be replaced with std::shared_ptr<Template>
and all uses of const Template * with std::shared_ptr< const Template >
. Then all the raw delete operations are not necessary, and the matches can be used safely.