[comp.lang.c++] efficient virtual functions in leaf functions

brucec@phoebus.phoebus.labs.tek.com (Bruce Cohen;;50-662;LP=A;) (09/14/90)

Here's a way for a class library developer to supply the class user with
leaf class member functions which can respond virtually when called in the
context of a base class object or object pointer, and inline when called in
the context of a leaf class object or object pointer.  It also allows the
user to derive from the leaf class and restore the virtuality of the
functions in the derived class.

I really don't think this is a big deal, but enough people have talked
about wanting to do something along these lines that I thought it would be
worth sharing.  And I can't help but think that someone else must have
thought of this before.

// test of concept for inlining virtual functions in leaf classes, while
// allowing the leaf to be subclassed and the virtuality of the function
// restored.
//
// The basic notion is to declare a public interface function (non-virtual,
// prefereably inline) in the base class, which calls a protected virtual
// function which does all the work.  Derived classes (other than leaves)
// simply redefine the virtual to do what is necessary.  Leaf classes
// overload  the interface function with an inline which does the actual
// work, then redefine the virtual function to call the interface function,
// so that the right thing will happen on a virtual call.
//
// If you want a derived class of the leaf which allows virtuality again,
// it just needs to overload the interface function to call the virtual,
// and put the working code back in the virtual.  One drawback: you will not
// be able to use the original leaf class as the root of the new
// inheritance graph for purposes of calling that virtual, but that is no
// big loss.
//
// This is a relatively brainless example which is small enough to actually
// look at the Cfront generated c code.  The code looks OK, and the output
// of the program is what you would expect:
//
// I'm a virtual Root
// I'm a virtual Stem.
// I'm a virtual Leaf.
// I'm a non-virtual Leaf.
// I'm a virtual Bud.
//

#include <stream.h>

class Root
{
  public:
    void Print();

  protected:
    virtual void print();
};

inline void Root::Print()
{
    cout << "I'm a virtual ";
    print();
}

void Root::print()
{
    cout << "Root\n";
}

class Stem : public Root
{
  protected:
    virtual void print();
};

void Stem::print()
{
    cout << "Stem.\n";
}

class Leaf : public Stem
{
  public:
    void Print();

  protected:
    virtual void print();
};

inline void Leaf::Print()
{
    cout << "I'm a non-virtual ";
    print();
}

void Leaf::print()
{
    cout << "Leaf.\n";
}


class Bud : public Leaf
{
  public:
    void Print();

  protected:
    virtual void print();
};

inline void Bud::Print()
{
    cout << "I'm a virtual ";
    print();
}

void Bud::print()
{
    cout << "Bud.\n";
}

main()
{
   Root* rp;

   rp = new Root;
   rp->Print();

   rp = new Stem;
   rp->Print();

   rp = new Leaf;
   rp->Print();

   Leaf leaf;
   leaf.Print();

   rp = new Bud;
   rp->Print();
}
--
---------------------------------------------------------------------------
NOTE: USE THIS ADDRESS TO REPLY, REPLY-TO IN HEADER MAY BE BROKEN!
Bruce Cohen, Computer Research Lab        email: brucec@tekcrl.labs.tek.com
Tektronix Laboratories, Tektronix, Inc.                phone: (503)627-5241
M/S 50-662, P.O. Box 500, Beaverton, OR  97077