<br>Hi Stuart,<br><br>--------------------------------------------------------------<br><div class="gmail_quote">On Fri, May 28, 2010 at 1:24 PM, Stuart Golodetz <span dir="ltr">&lt;<a href="mailto:itk@gxstudios.net">itk@gxstudios.net</a>&gt;</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">
Hi Luis,<br>
<br>
Thanks for the helpful response.<div class="im">1) When writing functions that take an image as an argument,<br><blockquote type="cite">
    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></div>
Not sure I follow what you mean here - if SmartPointers don&#39;t support
polymorphism, then doesn&#39;t that mean that this sort of thing won&#39;t work?<br>
<br>
struct B { virtual ~B() {} };<br>
struct D : B {};<br>
void f(itk::SmartPointer&lt;B&gt; b) {}<br>
...<br>
itk::SmartPointer&lt;D&gt; d;<br>
f(d);<br>
<br></div></blockquote><div><br>Exactly. <br>This code above doesn&#39;t work.<br><br>Here is a full example that illustrates the case:<br><br>----------------------------------------------------<br><br>#include &quot;itkImage.h&quot;<br>
#include &quot;itkObject.h&quot;<br><br>class B : public ::itk::Object<br>{<br>virtual ~B() {} <br>};<br><br>class D : public B {};<br><br>void f(itk::SmartPointer&lt;B&gt; b) {}<br>void g( B * b) {}<br><br>int main()<br>
{<br>  itk::SmartPointer&lt;D&gt; d;<br>  g(d);  // This works<br>  f(d);  // This doesn&#39;t<br>  return 0;<br>}<br><br><br>---------------------------------------------------<br><br> </div><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">
Whereas this always works by the rules of the language:<br>
<br>
void f(B *b) {}<br>
D *d;<br>
f(d);<br>
<br></div></blockquote><div>-------------------------<br><br>Yes,<br>This is the case that support polymorphism.<br><br>------------------------- <br></div><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">
I think I would understand what you mean if your last paragraph said
&quot;That is, if you use *raw* pointers...&quot; [emphasis mine]. Or am I
getting the wrong end of the stick? :)<div class="im"><br></div></div></blockquote><div>------------------------<br><br>My mistake.<br>Thanks for pointing this out.<br><br>When I wrote<br><br>&gt;    That is, if you use smart pointers, you can call that function<br>

&gt;    later with an argument that is a derived class of that image <br>
&gt;    type.<br>

<br>I actually meant to write<br><br>&gt;    That is, if you use *raw* pointers, you can call that function<br>
&gt;    later with an argument that is a derived class of that image <br>
&gt;    type.<br>

<br>Sorry about the mishap.<br><br> ----------------------------------------------------------------------------</div><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 class="im">
<blockquote 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></div>
I think I&#39;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&#39;t get destroyed as long as
I&#39;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&#39;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?</div></blockquote><div><br><br>That&#39;s exactly right.<br><br>The actual &quot;reference count&quot; is stored  in the image.<br>More specifically in the member variable:<br><br>                  m_ReferenceCount<br>
<br>which is defined in itkLightObject.h : line 141.<br><br>and the image inherits it through the chain:<br><br>itk::LightObject<br>itk::Object<br>itk::DataObject<br>itk::ImageBase<br>itk::Image<br><br><br></div><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 class="im"><br>
<blockquote type="cite">3) Please note that the construction<br>
  <br>
          const    Image::ConstPointer &amp;  ptr ....;<br>
  <br>
    prevents the internal mechanisms of the SmartPointer <br>
    from working, since the &quot;const&quot; keyword prevents the &quot;ptr&quot;<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></div>
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() --&gt; const &lt;--<br>
{ <br>
    if(m_Pointer) { m_Pointer-&gt;Register(); }<br>
}<br>
  <br>
void UnRegister() --&gt; const &lt;--<br>
{<br>
    if(m_Pointer) { m_Pointer-&gt;UnRegister(); }<br>
}<br>
<br></div></blockquote><div><br><br>Yes, <br>Ideally these methods should have been &quot;const&quot;.<br>Since the reference count of the object doesn&#39;t<br>really imply a change in its state.<br><br> </div><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">
I haven&#39;t really looked at the implications that would have elsewhere
though - any thoughts?<br>
<br></div></blockquote><div><br><br>The implications are huge...   :-/<br><br>In 2002 we attempted to fix the lack of <br>const-correctness in the pipeline, and<br>the effects propagated all over the toolkit<br>to the point where we have to give up.<br>
<br>In order to fix the lack of const-correctness <br>in the pipeline your will have to rewrite the<br>pipeline from scratch.  <br><br><br>Something that,<br>may or may not happen as part of ITKv4....<br><br><br><br></div>
<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">
Cheers,<br>
Stu<div><div></div><br></div></div></blockquote></div><br>