Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Virtual base class query

Status
Not open for further replies.

isaisa

Programmer
May 14, 2002
97
0
0
IN
Hi,
i am trying to understand the concept of virtual base class mechanism. i am not able to understand about it. as per my understanding, the virtual base class is shared in it's derived classes. i wanted to understand the internal implementation done by the compiler [similar to the Vptr and Vtbl implementation in case of using virtual function in class hairarchy]. so i need help in understanding how the virtual base class is shared to resolve the diamond shape problem.

thanks in advance.

Sanjay
 
Code:
class Aircraft
{
  double speed;
public:
  Aircraft(double maxspeed = 0):speed(maxspeed) {}
  virtual ~Aircraft() {}
  double maxSpeed(double maxspeed) 
  {
    double old=speed;
    speed=maxspeed;
    return old;
  }
  double maxSpeed() const { return speed; }
};

class Fighter: virtual public Aircraft
{
  int	missiles;
public:
  Fighter(double maxspeed, int rockets = 0):
    Aircraft(maxspeed),missiles(rockets) 
  {}
  ~Fighter() {}
  int nRockets() const { return missiles; }
};

class Bomber: virtual public Aircraft
{
  int	load;
public:
  Bomber(double maxspeed, int maxload = 0):
    Aircraft(maxspeed), load(maxload)
  {}
  int getLoad() const { return load; }
};

class F15E: public Fighter, public Bomber
{
public:
  F15E():Fighter(1500,6),Bomber(600,15000) // True speed?
  { 
     maxSpeed(1500); // Default Aircraft ctor was called!
  }
};
} // End of namespace USAF

int main(int argc, char* argv[])
{
  USAF::F15E	fb;
  cout << "Speed:\t" << fb.maxSpeed() << endl;
  cout << "Load:\t" << fb.getLoad() << endl;
  cout << "Rockets:" << fb.nRockets() << endl;
  return 0;
}
Now we can see: Aircraft has a (max) speed only, so Aircraft object is represented by its speed member var. Fighters and Bombers are Aircrafts and what about fighter-bomber category? Of course, a fighter-bomber is an aircraft (a fighter AND a bomber), but without virtual base classes it inherits two speeds (one as a Fighter Aircraft and another as a Bomber Aircraft). It's nonsense. So we use virtual inheritance at the beginning (in main aircraft categories declarations).

The example above illustrates the subtle moment: who can initialize a fighter-bomber speed - Fighter or Bomber constructor? In that case default Aircraft constructor called! So we need setter method for the speed in the base (Aircraft) class (setSpeed(double)).

May be it helps?..
 
Hi ArkM
Thanks for the quick response. I am still confused in the implementation at the compiler level. I tried to check with the example below for understanding.

class Base {
int m_data;
};

class Derived1 : public virtual Base {
};

class Derived2 : public virtual Base {
};

class Derived3 : public Derived 1, public Derived2 {
};

For the above classes,the size of the class objects are as under.

sizeof(Base) = 4 bytes
sizeof(Derived1) = 8 bytes
sizeof(Derived2) = 8 bytes
sizeof(Derived3) = 12 bytes

This is not clear as to why the Vptr kind of mechanism is implemented for Derived1 and Derived2. There is no declaration of virtual function in this case.
can you please hilight on this point?
Actually i am aware about the diamond shape issue in multiple inheritance and i have some idea about it's resolution using virtual base class. I am trying to understand the internal implemetation which the compiler does. If you could help me in that clarification, it will be of great help to me.

Thanks in advance
sanjay



 
I don't know exactly how MS implemented virtual base inheritance but let's see on the issue in general.

In common inheritance case a compiler knows all members (from base class too)offsets in derived class object. In virtual base inheritance it's amiss (for base class members). The offset of (unique) base class object (in diamond case, for example) depends on all virtual inheritance participants. The common approach to deal with virtualization (with minimum run-time overheads) is vtable: to add hidden field (4 byte pointer in 32-bit environment). This field increase sizeof(class) with virtual base.

Try the simplest case with empty Base class (w/o m_data member). You can see sizeof(Base) == 1 (no objects with sizeof == 0, but it's another story why), sizeof(D1) == sizeof(D2) == 4 (that's it!) and sizeof(D3) == 8 (D1+D2 vtable pointers).

May be it helps (you and me;)...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top