On Tue, Nov 17, 2009 at 9:23 AM, Roy Stogner <[email protected]> wrote:
>
> On Tue, 17 Nov 2009, Tim Kroeger wrote:
>
>> On Tue, 17 Nov 2009, Boyce Griffith wrote:
>>
>>>>> Can't you just call clear() in ~MyPreconditioner()?
>>>>
>>>> Sure, I can.  Actually, that's what I'm doing now.  But for that, still the
>>>> method Preconditioner::clear() does not have to exist, does it?
>>>
>>> I haven't used the Preconditioner class in libMesh, but this kind of
>>> init()/clear() functionality is useful for time-dependent problems in which
>>> you need to re-initialize the solver/preconditioner repeatedly. It is
>>> similarly useful for adaptive discretizations.
>>
>> Well, that might be right in a way.  However, at least, I would vote
>> for removing the call to clear() inside the destructor of the
>> Preconditioner class, since this is definitely not doing anything, but
>> it might make users believe it would call overloaded clear() methods.
>
> I agree, but let's wait on Derek's input.

Despite it being Item 9 in the 3rd ed. of "Effective C++" I admit to
being unaware that you should never call virtual functions in (base
class) constructors or destructors!  Having now read that item, it
does make some sense...

In a cursory examination, I haven't found a base class in Libmesh
whose constructor calls a virtual function expecting derived class
behavior, but we've followed the "virtual clear() in destructor"
paradigm in many places in the library, see NumericVector for one
other example.

Since this is potentially misleading to users deriving from LibMesh
classes:  "Hey, I don't need to call clear() in my destructor because
it's already done in the base class!" my vote would be to make all
"clear()-like" functions (functions intended to be used in
destructors) non-virtual in the library.  I suspect this will be
difficult to enforce in practice though...

The idea of a virtual clear() function seems like a nice one, but I
suspect it's rarely exactly what you want, assuming "what you want" is
to clear out the entire object, since (as we typically implement
clear()) it only clears data structures allocated in the derived class
and never subsequently calls the clear() method of its parent(s).  In
any case, trying to remember to call clear() all the way "up the
chain" would certainly be a maintenance nightmare.

As I understand the way destructors work, if you delete an object of
type derived through an object of type pointer-to-base, as long as the
base class destructor is declared virtual, the derived class
destructor will be called *in addition to* the destructor for *every*
intermediate type.  Correct?  I think this is the way we expect clear
to be used in most of our classes, and it doesn't require virtual.

-- 
John

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Libmesh-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libmesh-devel

Reply via email to