From -2799579495641991198
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f78e5,8c9f1307b83ac2db
X-Google-Attributes: gidf78e5,public
From: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Subject: Re: Q: virtual functions not overridable anymore?
Date: 1997/09/11
Message-ID: <3417EBB0.7682AF22@physik.tu-muenchen.de>#1/1
X-Deja-AN: 271684247
References: <01bcb109$1e790180$433574cf@worldnet.worldnet.att.net> <3404A0AE.6F7E@Eng.Sun.COM> <5uimip$l56@bgtnsc03.worldnet.att.net> <340D93AA.643A@Eng.Sun.COM> <3416BA58.46A1D41D@club-internet.fr>
X-Original-Date: Thu, 11 Sep 1997 15:01:36 +0200
Organization: [posted via] Leibniz-Rechenzentrum, Muenchen (Germany)
X-Auth: PGPMoose V1.1 PGP comp.std.c++ iQBVAwUBNBhPaEy4NqrwXLNJAQF3PAH/aqJDmXLJ/q1Z08pfCiBTr2KvdsUqpMNQ 3F7wLzhZUPUN5lk1YUjN2gOiHMSTZZ0kpDYYUjAnWQh7gq9ceqyLhA== =5AZy
Newsgroups: comp.std.c++
Originator: austern@isolde.mti.sgi.com


Christian Millour wrote:
> 
> Steve Clamage wrote:
> >
> > Cristian Georgescu wrote:
> > >
> > > The problem with 1. is that you may need a certain function to be virtual
> > > through the class hierachy inside your code, but you would like that in a
> > > certain leaf class (that is intended to be used by the user) the user
> > > should not override the virtual function.
> >
> > But why?
> >
> 
> I run into this problem everytime I attempt to nest `template methods'
> (see `Design Patterns' p 325), as in:
> 
> class Queryable {
>   ...
> public:
>   // template method
>   void query(Whatever & into) { do_query(into); }
> private:
>   // hook
>   virtual void do_query(Whatever & into) = 0;
> };
> 
> class Cached : public Queryable {
>   ...
> private:
>   // now the hook becomes itself a template method
>   virtual void do_query(Whatever & into) {
>     if (expired()) { renovate_cache(); expired(false); }
>     copy_cache(into);
>   }
>   // hooks
>   virtual void renovate_cache() = 0;
>   virtual void copy_cache(Whatever & into) = 0;
> };
> 
> classes derived from Cached should implement `renovate_cache'
> and `copy_cache' but should not override `do_query', whose
> job is done for good. Arguably, a derived class might extend
> do_query (provided it was made protected rather than private)
> as
> 
> void DerivedFromCached::do_query(Whatever & into) {
>   // before stuff
>   Cached::do_query(into);
>   // after stuff
> }
> 
> but any other form is likely to compromise Cached's semantics,
> which is rather distressing.
> 
> So maybe the design is wrong. But what are the alternatives ?

Maybe, instead of a keyword "final", we should have a keyword
like "force_call", which makes it an error not to call the base
class function when overriding it.
The force_call modifier should be allowed to be added for
overriding functions, but not to be removed (although it may
be omitted, just like virtual).

For example, your Cached class could define

virtual force_call void do_query(Whatever& into)

and thus ensure that every derived class must use this code
even if it overrides the function (i.e. it can add things to it,
but it can't replace it).

For example, the following would possibly be reasonable:

class ConditionallyCached: public Cached
{
private:
  virtual force_call void do_query(Whatever& info)
    {
      Cached::do_query(info);
      if(info.no_caching())
        expired(true);
    }
};

Of course, even with force_call, you could decide not to call
the overriden function by simply doing:

class Machiavelli: public Cached
{
private:
  virtual force_call void do_query(Whatever& info)
    {
      if(0) Cached::do_query(info); // trick the compiler
      info=Whatever("Never ask me.");
    }
};

But we know, C++ is not intended to protect against Machiavelli :-)
(BTW, such a class might even be useful for debugging!)
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your 
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu 
]



