Re: How to enforce a virtual fn is overloaded by derived class?
jaybus56 wrote:
Mhm, this is a nice question... but... Can you explain a little
deeper: what is the deeper sense of it?
This is a very good question.
You know, if one writes a base class the *inheritor* should know best,
whether it is necessary to overwrite the virtual funtion or not - not
the author of the base class. Am I wrong?
I think you can be wrong. Let me explain...
There are two ways that inheritance is often used:
1. The baseclass is extended, both in terms of interface and and
implementation.
2. An interface defined by the baseclass is implemented in derived classes.
Often, when #1 is the case, you have a few bad design decisions up front.
You see this e.g. when people start deriving from (concrete) string or
container classes or when the baseclass already includes everything and the
kitchen sink, like e.g. in a well-known widget-set wrapper.
Also typical there is that while the interface is extended, the
implementation is mostly just used, i.e. you rarely if ever have code from
the baseclass calling code from the derived class.
A typical example for case #2 is when you have a mere interface definition
as baseclass. E.g. for a general purpose digital output that would be
struct digital_out: private noncopyable
{
virtual ~digital_out()
{}
void set_value(bool v)
{ do_set_value(v); }
private:
virtual void do_set_value(bool v) = 0;
};
IOW, there is nothing to override here as it is only the derived class that
implements anything at all. Neither is there a base implementation nor
would one be possible!
class base {
void foo() {}
public:
virtual void bar() { foo(); } // base has some handler
};
template< class T>
class basehelper: public base {
public:
void bar() { // calls the appropriate foo
T* self = dynamic_cast< T*>( this);
self->T::foo();
}
};
This looks a bit like CRTP, but with two drawbacks:
1. It uses dynamic_cast instead of static_cast, which involves a greater
runtime overhead.
2. It doesn't even verify the returnvalue of the dynamic_cast, which kind of
defeats its very purpose.
Yes, CRTP is "unsafe" in that it can't guarantee that "this" really points
to a "T", but since it is only used in very restricted ranges and
(hopefully) well-documented and understood, that is accepted. For added
safety, an assertion with a dynamic_cast is used.
Uli
--
Sator Laser GmbH
Gesch??ftsf??hrer: Thorsten F??cking, Amtsgericht Hamburg HR B62 932
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]