Multiple inheritance for c
Advertisement
This presentation is the property of its rightful owner.
1 / 23

Multiple Inheritance for C++ PowerPoint PPT Presentation

Multiple Inheritance for C++. By Bjarne Stroustrup AT & T Bell Labs Murray Hill, NJ. PS_Coordinate { <List of ops> double x_; … };. PS_Point { <List of ops> PS_Coordinate pt_; };. Motivation for Multiple Inheritance. UG_Display { <List of ops> UG_Color color_;

Download Presentation

Multiple Inheritance for C++

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Multiple inheritance for c

Multiple Inheritance for C++

By

Bjarne Stroustrup

AT & T Bell Labs

Murray Hill, NJ


Motivation for multiple inheritance

PS_Coordinate

{

<List of ops>

double x_;

};

PS_Point

{

<List of ops>

PS_Coordinate pt_;

};

Motivation for Multiple Inheritance

UG_Display

{

<List of ops>

UG_Color color_;

UG_Layer layer_;

UG_Width width_;

};

PS_Spline {..};

PS_Bspline {…};

PS_Bcurve {..};

PS_Line

{

<List of ops>

PS_Coordinate start_;

PS_Coordinate end_;

};

UG_AdDisplay{..};

  • PS_* and UG_* are from different modules

  • The display properties are added to the CAD geometry for visualization and translation

  • Geometry used for operations like CAM, FEA etc.


Goals

Goals

  • A brief history of MI in C++

  • Myths, the need for this presentation.

  • How MI is to be implemented for different use cases

  • Controversies that surrounded MI – follows from the Myths

  • Actual overheads and conclusion


Multiple inheritance

Multiple Inheritance

  • Representation of various widgets in a windowing system.

  • Representation of various processors and architectures for a multi-machine. Multi-environment debugger

  • Allows combination of independent concepts into a composite concept.

  • N concepts can be married to M concepts in N+M ways using MI

    • To achieve the same thing we need N+M+N*M classes with duplication.


Some history

Some History

  • Made its appearance in Release 2.0 of Cfront

  • Bjarne considers having MI in Release 2.0 was a mistake

    • Not as important as parameterized types and exception handling

  • Reasons for implementing in 2.0

    • Fitted very well in to C++ type system

    • Could be implemented within Cfront

    • Considered to be difficult to implement

      • Brad Cox says impossible


Some history1

Some History

  • Solution conceived in 1984 with Stein Krogdal of Simula

  • Solution similar to Ole-Johan Dahl considered in 1966.

  • Solution rejected because it would have complicated the GC.

  • BS later mentions “Fashion affected the sequence of events”


Myths

Myths

  • Complicates Programming Language significantly

  • Is hard to implement

  • Expensive to run

  • Are the above really true?


C object model

C++ Object Model

class 2dpoint {

float x, y;

int translate (const 2dpoint *);

};

float y

  • Static data members outside the class

  • Static and non static function members outside the class object

  • Non-static data members within the object

float x

2dpoint *pt;

pt->translate (…);= f__F12dpoint (pt,…)

  • Based on the Simple Model

  • Optimized for time and space overhead.

  • Table driven model is not efficient


Object model with single inheritance

Object Model with Single Inheritance

class 3dpoint: 2dpoint {

float z;

int translate (const 3dpoint *);

};

float z

float y

float x

3dpoint *pt;

pt->translate (3dpoint *);= f__F23dpoint (pt, 3dpoint *)

3dpoint *pt;

pt->translate (2dpoint *);= f__F13dpoint (pt, 2doint *);


Inheritance with virtual functions

Inheritance with Virtual functions

class A { float a; virtual void f (float);

virtual void g (float);

virtual void h (float);

};

class B : A {float b; void f (float);};

class C: B {float c; void g (float);};

float a

Object Layout for Object of type C

float b

float c

__vptr

type_info

C::g ()

C *pg;

Pg->g (2.0); 

(*(pg->__vptr[0])) (pg, 2.0)

B::f ()

A::h ()


Multiple inheritance simple

class A { ..};

class B {..};

class C:A, B {};

C is a A & a B

The declaration

class C:B, A {};

is equivalent to above

Assume A has a method af () and B has a method bf ()

Multiple Inheritance – Simple

pf

A Part

C *pf;

pf->bf ();

B Part

B::bf defined from here

C Part

delta B

f__f1B(B*)((char*pf+delta B))

For ambiguities in this case see section 4.3 of the paper


Interesting use cases

Casting

C* pc;

B* pb;

pb=(B*)pc;

/*pb =(B*)((char*)pc+delta(B)) */

pb=pc;

/*pb = (B*)((char*)pc+delta(B))*/

pc=pb;

// error: cast needed

pc=(C*)pb;

/*pc = (C*)((char*)pb-delta(B))*/

Comparisons

pc == pb;

/* pc ==(C*)pb or equivalently (B*)pc == pb which is,(B*)((char*)pc+delta(B)) == pb or equivalently pc == (C*)((char*)pb-delta(B))

*/

Zero Valued pointers

C* pc = 0;

B* pb = 0;

if (pb == 0) ...

pb = pc; // pb = (B*)((char*)pc+delta(B))

if (pb == 0) ..

So use pb = (pc ==0)?0: (B*)((char*)pc+delta(B))

Interesting Use Cases


Mi with virtual functions

class A {virtual void f ()};

class B {

virtual void f ();

virtual void g ();

};

class C:A, B {void f ();};

MI – with Virtual functions

A Part

struct vtbl_entry {

void *(fct) (); int delta;};

B Part

C::f ()

-delta B

__vptr

B::g ()

0

C Part

__vptr

C::f ()

0

B::g ()

delta B

B *pf = new C;

pf->f (); // Should call C::f ()

For ambiguities in this case see section 5.2 of the paper


Multiple inclusions

Multiple Inclusions

  • A class can have any number of base classes like

    class C:A, B, D, E, F {..};

  • Illegal to specify a class name twice in the list

    class C:A, B,B, F {..}; //illegal

  • A may be included more than once as a base class

    class L {..}; class A:L {..}; class B:L {..}; C:A,B {..};

  • For scope resolution and type checking please see sec. 6.2 and 6.3 in paper.


Mi with virtual base classes

MI with Virtual Base Classes

  • Independent MI

  • One Object of the base class in the final derived class, irrespective of the number of times derived.

  • Base classes can be declared virtual to achieve the above like this

    class AW: virtual W {...};

    class BW: virtual W {...};

    class CW:AW,BW{};

  • W shared between AW and BW

  • Except for the unique object, this is just similar to the non-unique case.


Object model with virtual base class

Casting allowed from the derived class to the base class but not vice-versa

The latter requires a “back-pointer” and unsuitable C++.

Use virtual functions instead 

Object Model with Virtual Base Class

ptr to w

ptr to w

ptr to aw

ptr to cw

AW Part

AW Part

W Part

BW Part

CW Part

W Part


Virtual functions

class W {

virtual void f();

virtual void g();

virtual void h();

virtual void k();

};

class AW: virtual W {void g();};

class BW: virtual W {void f();};

class CW: AW ,BW {void h();};

CW* pcw = new CW;

pcw->f(); // BW::f()

pcw->g(); // AW::g()

pcw->h(); // CW::h()

((AW*)pcw)->f(); // BW::f();

Virtual Functions

ptr to w

d (BW) –

d (W)

BW::f

AW Part

AW::g

-d (W)

-d (W)

CW::h

BW Part

0

W::k

CW Part

vptr

W Part

Ambiguities detected at

vtbl construction time


Virtual bases

Virtual Bases

  • Method combination, not supported in C++

    • Call and return a solution to mimic :before () and :after ()

  • Method combination can be achieved using manually

    • Problem is to avoid multiple calls to the same function in the virtual class

    • See 7.3 of the paper for a good example

  • Constructors and Destructors

    • Ctor for base classes are called before Ctor for derived classes

    • Dtors are reverse

    • Ctors are called as they appear in the list but the virtual base is constructed first.


Controversies

Controversies

  • Tom Cargill, 1991, First C++ Conference, Santa Fe

  • Jim Waldo, 1993

  • Smalltalk doesn’t implement MI

  • BS first implementation had additional overhead.

  • BS focused on implementation.

  • Too hard to use, poor design an buggy code

  • Delegation is an alternative

  • Makes GC and tools difficult.


Alternative object layout for mi

Alternative Object Layout for MI

class A {virtual void f ()};

class B {

virtual void f ();

virtual void g ();

};

class C:A, B {void f ();};

A Part

B Part

__vptr

B::g

C Part

__vptr

C::f ()

0

  • Compact virtual function tables

  • Faster calls to virtual functions if delta is 0

    • Delta is 0 for SI

  • Less portable

  • ‘goto’ is not supported on m/c architectures

this -= delta (B)

goto c::f


Delegation

Presented at EUUG in May 1987

Class specified like this

class B {int b; void f();};

class C: *p {B*p; int c;}

The :*p meant that something like this

void f (C* q)

{

q->f ();

//meaning q->p->f();

}

Delegation

B *p

int c

int b

  • Very promising as delegation could be used to reconfigure object at run-time

  • Implementation trivial, run-time space efficiency ideal

  • Bugs and confusion, removed from Release 2.0

    • Functions in delegating class do not override

    • Delegated fn. cannot call delegating fn,


Overheads

Overheads

  • One operation with a constant for each use of a member in a base class.

    • Only with MI

  • One word per function in each vtbl(to hold the delta).

    • Normal use case

  • One memory reference and one operation for each call of a virtual function.

    • Normal use case

  • One memory reference and one operation for access of a base class member of a virtual base class.

    • Only with MI


Conclusions

What makes a language facility hard to use?

Lots of rules.

Subtle differences between rules.

Inability to automatically detect common errors.

Lack of generality.

Deficiencies.

Ambiguities are illegal.

Rules for use of members are what they were for single inheritance.

Visibility rules are what they were for single inheritance.

Initialization rules are what they were for single inheritance.

Violations of these rules are detected by the compiler.

Easier to implement

Portability is not affected

Conclusions


  • Login