[gnu.g++.bug] multiple inheritance and virtual functions

loepere@westford.ccur.com (07/04/89)

If I declare a class to be derived from multiple classes in which more
than one has virtual functions, the resultant object will have more
than one _vtbl entry (one for each class with virtual functions).
Unfortunately, the constructor for the derived class only sets
(changes) the first _vtbl entry, making the other virtual functions
non-virtual. - Keith 

#include <stream.h>
class singer
{
 public:
  singer (const int a_preferred_key);

  virtual void sing (ostream &s);

 protected:
  int preferred_key;
};

inline singer::singer (const int a_preferred_key)
{
  preferred_key = a_preferred_key;
}

void singer::sing (ostream &s)
{
  s << "La";
  for (int i = 0; i < preferred_key; i++)
    s << "a";
};

enum dancer_t {ballet, jazz, tap};

class dancer
{
 public:
  dancer (const dancer_t a_type);

  virtual void dance (ostream &s);

 protected:
  dancer_t type;
};

inline dancer::dancer (const dancer_t a_type)
{
  type = a_type;
}

void dancer::dance (ostream &s)
{
 switch (type)
   {
   case ballet:
     s << "^v^v^v^v^v^v";
     break;
   case jazz:
     s << "<><><><><><>";
     break;
   case tap:
     s << "............";
     break;
   }
}

enum cat_t {persian, tabby, siamese};

class performing_cat : public dancer, public singer
{
 public:
  performing_cat (const cat_t cat_type, const int preferred_key, const dancer_t dance_type);

  void sing (ostream &s);

  void dance (ostream &s);

 protected:
  cat_t type;
};

inline performing_cat::performing_cat (const cat_t cat_type, const int preferred_key, const dancer_t dance_type)
     : singer (preferred_key), dancer (dance_type)
{
  type = cat_type;
}

void performing_cat::sing (ostream &s)
{
  s << "Me";
  for (int i = 0; i < preferred_key; i++)
    s << "e";
  for (i = 0; i < preferred_key; i++)
    s << "o";
  s << "ow";
}

void performing_cat::dance (ostream &s)
{
  dancer::dance (s);
  s << "(pounce)";
}

int main ()
{
  performing_cat morris (tabby, 4, jazz);

  singer *one = &morris;
  one->sing (cout);
  cout << "\n";

  dancer *two = &morris;
  two->dance (cout);
  cout << "\n";
  return 0;
}