<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
<title></title>
</head>
<body bgcolor="#ffffff" text="#000000">
Luis Ibanez wrote:
<blockquote
cite="mid:AANLkTik0KEwsBVzEvhVKR2oNPMJxffOz6m-O6r47oTow@mail.gmail.com"
type="cite"><br>
Hi Stuart,<br>
<br>
<snip><br>
<div class="gmail_quote">
<div><br>
When I wrote<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>
<br>
I actually meant to write<br>
<br>
> That is, if you use *raw* pointers, you can call that function<br>
> later with an argument that is a derived class of that image <br>
> type.<br>
<br>
Sorry about the mishap.<br>
</div>
</div>
</blockquote>
No probs - just wanted to double-check.<br>
<blockquote
cite="mid:AANLkTik0KEwsBVzEvhVKR2oNPMJxffOz6m-O6r47oTow@mail.gmail.com"
type="cite">
<div class="gmail_quote">
<div> ----------------------------------------------------------------------------</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'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?</div>
</blockquote>
<div><br>
<br>
That's exactly right.<br>
<br>
The actual "reference count" 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>
</div>
</div>
</blockquote>
Ah right, passing raw pointers around makes a bit more sense in that
case :) I was in shared_ptr mindset...<br>
<blockquote
cite="mid:AANLkTik0KEwsBVzEvhVKR2oNPMJxffOz6m-O6r47oTow@mail.gmail.com"
type="cite">
<div class="gmail_quote">
<div><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 & 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>
</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() --> 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>
</div>
</blockquote>
<div><br>
<br>
Yes, <br>
Ideally these methods should have been "const".<br>
Since the reference count of the object doesn't<br>
really imply a change in its state.<br>
</div>
</div>
</blockquote>
<br>
In hindsight, I'm not sure that in this particular case the const-ness
or otherwise of those methods is actually the problem (see my other
post). When you do:<br>
<br>
const Image::ConstPointer& cptr = ptr;<br>
<br>
that creates a temporary to which cptr is then bound. In the
constructor of the temporary (the point at which you call Register()),
*this isn't const, so there's no problem. AFAICS the problem is that
there's no implicit conversion from a Pointer to a ConstPointer - one
way of changing that is to add the templatised constructor I mentioned
in my other message:<br>
<br>
template <typename T>
<br>
SmartPointer(const SmartPointer<T>& p)
<br>
: m_Pointer(p.GetPointer())
<br>
{ this->Register(); }<br>
<br>
If you add that, the problem seems to go away (I tried it, and there
didn't seem to be a problem). The question is whether that might break
something elsewhere (especially since itk::SmartPointer is a pretty
vital part of ITK which simply has to always work).<br>
<blockquote
cite="mid:AANLkTik0KEwsBVzEvhVKR2oNPMJxffOz6m-O6r47oTow@mail.gmail.com"
type="cite">
<div class="gmail_quote">
<div> </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'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>
</div>
</div>
</blockquote>
I'm not surprised! Whenever I've had to retrofit const-correctness to
one of my code bases, it's always a complete nightmare :)<br>
<br>
That being said, I wonder whether adding the above constructor (as
opposed to sorting out const-correctness generally) actually causes any
problems. If not, is there anywhere I can submit it for proper
consideration? I realise that suggesting even a minor change to
something as fundamental as itk::SmartPointer is probably a big deal,
but I thought I should ask just on the off-chance. I guess it partly
depends on whether allowing the implicit conversion is considered
desirable - what do you think?<br>
<blockquote
cite="mid:AANLkTik0KEwsBVzEvhVKR2oNPMJxffOz6m-O6r47oTow@mail.gmail.com"
type="cite">
<div class="gmail_quote">
<div>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>
</div>
</div>
</blockquote>
I'll watch and wait :) I guess that probably won't happen till after
I've finished my doctorate though.<br>
<br>
Cheers,<br>
Stu<br>
</body>
</html>