From: Daniel T. on
"Leslie Sanford" <jabberdabber(a)bitemehotmail.com> wrote:
> "Daniel T." wrote:

> > To expand on HSs example... How is your code above any different than:
> >
> > class BaseInterface {
> > public:
> > virtual void DoSomething() = 0;
> > };
> >
> > class BaseImplementation {
> > public:
> > void DoSomething() { /* Yadda, yadda...*/ }
> > };
> >
> > class DerivedClass : public BaseInterface {
> > BaseImplementation impl;
> > public:
> > void DoSomething() {
> > impl.DoSomething();
> > // Yadda, yadda...
> > }
> > };
> >
> > In your code, implementation inheritance is used, in my example it is
> > not. As long as the BaseClass contains no data and has no non-virtual
> > member functions, your example is every bit as flexible as mine and your
> > example requires fewer classes.
>
> Ok, but what if the BaseClass does have data?

Then you are in danger of something called the "brittle base class
problem" (Google "brittle base class Stroustrup" for example.) As you
have learned, when you have a brittle base class, the derived types have
to go through extra pains to make sure the base class is kept in a valid
state and changing the base class implementation is especially dangerous.

> In the situation I described above, the base class's virtual
> methods had behavior that managed the class's state. If a derived
> class overrides one of those methods and does not call the base
> class method when it is called, the class's invariants may be
> violated. I guess there's something about this that just doesn't
> sit right with me. You'd have to rely on documenation to know
> when/if you have to call the base class's method.
>
> Should a base class be designed in such a way that an overriden
> method can always call the base class's method without bad things
> happening?

No, a base class should always be designed without member-variables. If
this is impossible or impractical to do in some cases, then the common
idiom in C++ is to make sure that none of the virtual member-functions
are public. If the base class is the only one that calls the virtual
member-functions, then it can make sure that the right things are done
by the derived classes. (I forgot what it's called, but its basically
the Template Method pattern.)

class Base {
public:
void foo() {
// do whatever the base class needs to do before call (if anything)
doFoo();
// do whatever the base class needs to do after call (if anything)
}
private:
virtual void doFoo(); // can be pure or not as desired
};
From: Diego on
On Jan 11, 5:45 pm, "Leslie Sanford" <jabberdab...(a)bitemehotmail.com>
wrote:
> As a general rule, I shy away from implementation inheritance. However, I do
> sometimes find it useful. My question is whether it's considered bad design
> for a derived class method to call the base class method it is overriding.
> Something like this:
>
> class BaseClass
> {
> public:
> virtual void DoSomething();
>
> };
>
> void BaseClass::DoSomething()
> {
> // Yadda, yadda...
>
> }
>
> class DerivedClass : public BaseClass
> {
> public:
> void DoSomething();
>
> };
>
> void DerivedClass::DoSomething()
> {
> BaseClass::DoSomething();
>
> // Yadda, yadda...
>
> }

this may be only a matter of personal preference, but I usually avoid
using inheritance only to reuse code

I use inheritance only to express the IS A relationship and to
implement the Template Design Pattern:

class BaseClass
{
public:
void DoSomething() { pre(); do_DoSomething(); pos(); }
.... other interface methods ...
virtual void do_DoSomething() { ... }
.... other template implementation methods...
};

class DerivedClass
{
public:
virtual void do_DoSomething() { yadda yadda yadda }
.... other template implementation methods...
};

Diego
HP
From: Alexandr Savinov on
Leslie Sanford schrieb:
> "Daniel T." wrote:
>> "Leslie Sanford" wrote:
>
> <snip>
>
>> Note, the derived class needs to know that about every base class method
>> (if and when to call it.) It's fair to say that such information is
>> required of every method/function in the program. So its not much of a
>> burden.
>
> I was using a third-party library recently in which I had a hard time
> tracking down an obscure bug. I had derived a class from one of the
> library's base classes. This class has many virtual methods that you can
> override to provide your own custom behavior.
>
> The problem turned out to be that I wasn't calling the base class method in
> my derived class's overriden method. This requirement wasn't mentioned any
> where in the documentation. I guess what would be nice would be some type of
> language mechanism that would enforce the correct policy, when/if to call
> the base class's method in a derived classes overriden version of that
> method.

Yes, this logic is necessary but it is opposite to the main logic of
inheritance and method overriding in OOP. The main idea is that base
methods have precedence over derived methods or base methods override
child class methods. In this case the base method is guaranteed to do
what it has to do in order to maintain the base object in consistent
state before the child method can start. However, in OOP it is hardly
possible to maintain this feature because actually it is not a feature
or mechanism but rather a quite different way of thinking about
responsibilities and how a system works.

In particular, such a behaviour is supported in the concept-oriented
programming where both strategies are possible:

Introduction: http://conceptoriented.com/papers/CopInformalIntroduction.html

Discussion: http://www.theserverside.com/news/thread.tss?thread_id=47699

This mechanism in CoP is referred to as *dual methods* because each
method can be defined two times: one version for external use and one
version for internal use. Accordingly, the external version overrides
child methods (and intercepts all incoming calls by guaranteeing
consistency of its state). The internal version (as usual in OOP)
overrides base methods and intercepts all calls from inside. Such a
design allows us to resolve the responsibility cycle.

A similar mechanism is also provided in the Beta programming language
(inner methods).

>> To expand on HSs example... How is your code above any different than:
>>
>> class BaseInterface {
>> public:
>> virtual void DoSomething() = 0;
>> };
>>
>> class BaseImplementation {
>> public:
>> void DoSomething() { /* Yadda, yadda...*/ }
>> };
>>
>> class DerivedClass : public BaseInterface {
>> BaseImplementation impl;
>> public:
>> void DoSomething() {
>> impl.DoSomething();
>> // Yadda, yadda...
>> }
>> };
>>
>> In your code, implementation inheritance is used, in my example it is
>> not. As long as the BaseClass contains no data and has no non-virtual
>> member functions, your example is every bit as flexible as mine and your
>> example requires fewer classes.
>
> Ok, but what if the BaseClass does have data? In the situation I described
> above, the base class's virtual methods had behavior that managed the
> class's state. If a derived class overrides one of those methods and does
> not call the base class method when it is called, the class's invariants may
> be violated. I guess there's something about this that just doesn't sit
> right with me. You'd have to rely on documenation to know when/if you have
> to call the base class's method.

In OOP it is always has to be done manually. So child class has to think
for the base class and actually work for it and execute its logic. This
leads to the situation where parent code is distributed all over the
child classes and the system has bad separation of concerns. It is
possible to automate it using various special techniques (like
preprocessing) but there is no principal solution within OOP. This ios a
consequence of the fact, that OOP is known to be not able to work with
cross-cutting concerns.