<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
<div class="moz-text-html" lang="x-western"> Hi Luis,<br>
<br>
Thanks for the helpful response.<br>
<br>
Luis Ibanez wrote:<br>
<blockquote
cite="mid:AANLkTilPJ0RGcfGsh8zehRly9kfrosCafdDkjPRBJfjQ@mail.gmail.com"
type="cite">Hi Stuart,<br>
<br>
<br>
Thanks for your detailed question.<br>
<br>
<br>
1) When writing functions that take an image as an argument,<br>
we usually use a Raw pointer instead of a Smart Pointer.<br>
<br>
The reason is that SmartPointers will not do polymorphism.<br>
<br>
That is, if you use smart pointers, you can call that function<br>
later with an argument that is a derived class of that image <br>
type.<br>
</blockquote>
Not sure I follow what you mean here - if SmartPointers don't support
polymorphism, then doesn't that mean that this sort of thing won't work?<br>
<br>
struct B { virtual ~B() {} };<br>
struct D : B {};<br>
void f(itk::SmartPointer<B> b) {}<br>
...<br>
itk::SmartPointer<D> d;<br>
f(d);<br>
<br>
Whereas this always works by the rules of the language:<br>
<br>
void f(B *b) {}<br>
D *d;<br>
f(d);<br>
<br>
I think I would understand what you mean if your last paragraph said
"That is, if you use *raw* pointers..." [emphasis mine]. Or am I
getting the wrong end of the stick? :)<br>
<blockquote
cite="mid:AANLkTilPJ0RGcfGsh8zehRly9kfrosCafdDkjPRBJfjQ@mail.gmail.com"
type="cite"> If you look at most ITK filters, you will find that
raw pointers<br>
are used in the API, for passing and receiving images.<br>
<br>
However, when we call those functions we pass a SmartPointer<br>
to them (since SmartPointers know how to cast themselves as<br>
raw pointers).<br>
<br>
<br>
2) The only case in which you may want to pass an image<br>
SmartPointer as argument to a function is when you are<br>
creating that image inside the function. <br>
<br>
In that case, passing the SmartPointer by reference is<br>
a reasonable choice.<br>
</blockquote>
I think I've been trying to use itk::SmartPointer as a
boost::shared_ptr, which may not be the best plan :) The idea being
that the pointed-to image or whatever won't get destroyed as long as
I'm holding an itk::SmartPointer to it, so I can construct it
somewhere, pass the itk::SmartPointer into a function, store a copy of
the itk::SmartPointer somewhere else and not worry if the original
itk::SmartPointer to the image no longer exists.<br>
<br>
What I've been missing is that itk::SmartPointer appears to use
*intrusive* reference-counting (i.e. the reference count is stored in
the image itself), so that if I pass in a raw image pointer to a
function I can then construct a separate itk::SmartPointer the other
end from it that will share the reference count with the original
itk::SmartPointer. Is that right?<br>
<blockquote
cite="mid:AANLkTilPJ0RGcfGsh8zehRly9kfrosCafdDkjPRBJfjQ@mail.gmail.com"
type="cite">3) Please note that the construction<br>
<br>
const Image::ConstPointer & ptr ....;<br>
<br>
prevents the internal mechanisms of the SmartPointer <br>
from working, since the "const" keyword prevents the "ptr"<br>
variable from changing. (strictly speaking it prevents the<br>
smart pointer from calling the non-const method Register()<br>
on the object that it points to).<br>
</blockquote>
Offhand, I think that could be easily changed by making Register() and
UnRegister() const methods, since that would only have the effect of
making m_Pointer itself const, not the ObjectType it points to:<br>
<br>
/** The pointer to the object referrred to by this smart pointer. */<br>
ObjectType* m_Pointer;<br>
<br>
void Register() --> const <--<br>
{ <br>
if(m_Pointer) { m_Pointer->Register(); }<br>
}<br>
<br>
void UnRegister() --> const <--<br>
{<br>
if(m_Pointer) { m_Pointer->UnRegister(); }<br>
}<br>
<br>
I haven't really looked at the implications that would have elsewhere
though - any thoughts?<br>
<br>
Cheers,<br>
Stu<br>
<blockquote
cite="mid:AANLkTilPJ0RGcfGsh8zehRly9kfrosCafdDkjPRBJfjQ@mail.gmail.com"
type="cite"> Regards,<br>
<br>
<br>
Luis<br>
<br>
<div class="gmail_quote"><br>
-------------------------------------------------------------------------<br>
On Thu, May 27, 2010 at 1:21 PM, Stuart Golodetz <span dir="ltr"><<a
moz-do-not-send="true" href="mailto:itk@gxstudios.net">itk@gxstudios.net</a>></span>
wrote:<br>
<blockquote class="gmail_quote"
style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div bgcolor="#ffffff" text="#000000">
<div style="font-family: -moz-fixed; font-size: 13px;"
lang="x-western">
<pre>Hi,
Hope this is the right place to post this. I was just wondering if
there's a reason why itk::SmartPointer was designed so as not to allow e.g.
itk::Image<int,3>::Pointer image;
const itk::Image<int,3>::ConstPointer& cimage = image;
?
The equivalent with boost::shared_ptr is allowed, e.g.
boost::shared_ptr<int> p(new int);
const boost::shared_ptr<const int>& cp = p;
This doesn't seem like a major problem, until you start writing
functions taking const itk::Image<...>::ConstPointer& parameters - at
which point it won't let you pass a normal Pointer in without explicitly
constructing a ConstPointer from it. Now the types are often quite long,
and it's annoying to have to add extra typedefs in the calling code just
for that purpose. Duplicating the functions with const
itk::Image<...>::Pointer& parameters doesn't work either, because you
get a combinatorial explosion when you have multiple such parameters.
For instance, with 3 parameters, you have to create functions with
combinations:
const Pointer&, const Pointer&, const Pointer&
const Pointer&, const Pointer&, const constPointer&
const Pointer&, const ConstPointer& const Pointer&
// more here
const ConstPointer&, const ConstPointer& const ConstPointer&
This seems like an unproductive way to spend one's time, to say the
least. The only other "reasonable" alternative I've managed to come up
with that doesn't either (a) clutter up the call site or (b) cause the
combinatorial explosion just outlined, is to just use the non-const
Pointers everywhere and abandon the idea of making the code
const-correct. But that seems defeatist to me <span><span> :) </span></span> Please could you tell
me if there's something I'm missing? (And if so, what?)
Cheers,
Stuart
</pre>
</div>
</div>
<br>
_____________________________________<br>
Powered by <a moz-do-not-send="true" href="http://www.kitware.com"
target="_blank">www.kitware.com</a><br>
<br>
Visit other Kitware open-source projects at<br>
<a moz-do-not-send="true"
href="http://www.kitware.com/opensource/opensource.html"
target="_blank">http://www.kitware.com/opensource/opensource.html</a><br>
<br>
Kitware offers ITK Training Courses, for more information visit:<br>
<a moz-do-not-send="true"
href="http://www.kitware.com/products/protraining.html" target="_blank">http://www.kitware.com/products/protraining.html</a><br>
<br>
Please keep messages on-topic and check the ITK FAQ at:<br>
<a moz-do-not-send="true" href="http://www.itk.org/Wiki/ITK_FAQ"
target="_blank">http://www.itk.org/Wiki/ITK_FAQ</a><br>
<br>
Follow this link to subscribe/unsubscribe:<br>
<a moz-do-not-send="true"
href="http://www.itk.org/mailman/listinfo/insight-users"
target="_blank">http://www.itk.org/mailman/listinfo/insight-users</a></blockquote>
</div>
</blockquote>
</div>
</body>
</html>