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
