[Insight-users] Using Polymorphism with itk::KernelTransform

Luis Ibanez luis.ibanez@kitware.com
Mon, 27 Jan 2003 10:39:19 -0500


Jim, Ofri

Yeap, I missed the point here.

Returning the raw pointer will only work if a
SmartPointer is kept somewhere in order to prevent
the reference count of the newly created transform
to drop to zero.

Jim's option (2) seems to be the best solution for
this case.

We can afford to return raw pointers from most of
the filters because they keep a list of smart
pointers to their inputs and output.


    Luis


------------------------------------------------


Miller, James V (Research) wrote:

> I am not sure this will work.  I think if you return the 
> raw pointer, the local smart pointer will deallocate the 
> memory before the calling routine has the chance to cache
> the pointer in another smart pointer.
> 
> There are two general options for dealing with this:
> 
> 1. Cache the transform in an ivar of a class so that the 
> smart pointer does not go out of scope. This is probably
> not appropriate here but we use it in other parts of the toolkit.
> 
> 2. Return a smart pointer to a base class. If the calling code
> knows what type of transform it requested, it can store it into
> the appropriate smart pointer type.
> 
> 
> BaseTransformType::Pointer createTransform(.....);
> 
> MyTransformType::Pointer myTransform 
>     = dynamic_cast<MyTransformType *>
>         (createTransform( sourcePoints, targetPoints,
>                           typeEnum).GetPointer() );
> 
> 
> The createTransform routine will call the appropriate new routine
> but send back a smart pointer to a base class
> 
> BaseTransformType::Pointer createTransform(...., typeEnum)
> {
>    switch (typeEnum)
>    {
>       case ThinPlateSplineTransform:
> 		return itk::ThinPlateSplineTransform::New().GetPointer();
> 		break;
>       case .....
>       case .....
>    }
> }
> 
> 
> 	
> 
> }
> 
> 
> 
>>Returning raw pointers is done all over the toolkit. The
>>only precaution to take is to make sure that the raw pointer
>>is received by a SmartPointer or to make sure that there is no
>>reason for the object to be destroyed while its raw pointer
>>is still in use.
>>
>>What you are doing is perfectly reasonable and conforms
>>to the typical use of ObjectFactories.
>>
>>Here is a possible scenario:
>>
>>typedef
>>itk::KernetTransform< MyCoordType,
>>                       MyDimension > BaseTransfomType;
>>
>>BasetTransformType::Pointer myTransfom =
>>      createTransfom( sourcePoints, targetPoints, typeEnum );
>>
>>With the function signature
>>
>>    BasetTransformType * createTransform(...etc)
>>
>>and, inside "createTransform()" you use some logic to decide
>>what type of transform to construct and return. You will
>>create this specific transform using its New() method and
>>pass the result to a local SmartPointer. Then, return the
>>raw pointer of this SmartPointer like
>>
>>    BaseTrasnformType::Pointer newTransform
>>                           = SpecificTransform::New();
>>
>>    return  newTrasform.GetPointer();
>>
>>
>>In this way, by the time the raw pointer is assigned to "myTransform"
>>the SmartPointer that was created in the function has been destroyed
>>and the reference count of the actual transform has been decremented
>>by 1. However, the reception of the transfrom in the SmartPointer
>>"myTransform" has also incremented the count by 1 and will keep the
>>transform alive.
>>
>>
>>
>