C++ Object Model

Classes are abstract types. Objects are instances of that type.

Three distinctive aspects of an OO System • Encapsulation Classes group related data and methods • Inheritance Derived classes extend and refine existing abstractions ... the design of consistent, intuitive, and useful class hierarchies is a complex and difficult art. • Dynamic Binding (polymorphism) Delay selection of appropriate abstraction implementation until program execution. ... OO programming is abstract data types with polymorphism

C++ Object Model 1 of 19 Lecture 8 EECS 498 Winter 2000

Aspects to Examine

• Distinctive Types of Programming • Semantics of Constructors • Semantics of Data • Semantics of Functions • Semantics of Construction, Destruction & Copy

C++ Object Model 2 of 19 Lecture 8 EECS 498 Winter 2000 Distinctive Types of Programming

• Procedural char *target, *source = “Hello World!”; target = malloc( strlen( source )); strcpy( target, source ); • Abstract Data Type String target, source = “Hello World!”; target = source; if (source == target) ... • Object Oriented class B { virtual int F(int) {return 1;} /* pure? /; } class D : B { virtual void F(int) { return 2;} } class E : B { virtual void F(int) { return 3;} } ... B *b = new B, B *d = new D, E *e = new D; cout << b->F() << d->F() << e->F() << endl;

Object oriented model requires reference to operating object. Referred to as this (self, current, etc.) Often first parameter to function

C++ Object Model 3 of 19 Lecture 8 EECS 498 Winter 2000

Storage Layout

Procedural • Storage sizes are known at compile time Pointers have fixed size on target platform Data namespace encapsulated in type structure Function namespace global Abstract Data Types • Namespace for functions bound to data structure Signature of function is name, result type, parameter types Object Oriented • Virtual functions invocation structure Virtual base classes A virtual base class occurs exactly once in a derived class regardless of the number of times encountered in the class inheritance heirarchy.

Great source of inefficiency.

C++ Object Model 4 of 19 Lecture 8 EECS 498 Winter 2000 Sample Class & Object Layout type_info for Point class Point float m_x { public: Point( float xval ); __vptr__Point virtual ~Point(); // -- accessor function float x() const; virtual Table Point::~Point() static int PointCount(); for Point protected: virtual ostream& print(ostream &os) const; static int Point::print(ostream&) Point::m_PointCount float m_x; static int m_PointCount; } Point::Point(float)

static int Point::PointCount() float Point::x()

• Statics are held in global namespace. Static data has global lifetime. VTable is class specific. • Non-static data held in object-specific allocated structure.

C++ Object Model 5 of 19 Lecture 8 EECS 498 Winter 2000

Semantics of Constructors

Constructors are class specific functions which initialize a new instance of an object to a known state. • User defined Constructor Can be overloaded. • Non-trivial Default Constructor • Non trivial implies not Bitwise copying

When is default constructor non-trivial? a)If class contains a member with non-trivial constructor b)If class is derived from a class with non-trivial constructor c)If class declares (or inherits) a virtual function d)If class is derived from a virtual base class.

C++ Object Model 6 of 19 Lecture 8 EECS 498 Winter 2000 Copy Constructors What program fragments require object copying? a)Simple Initialization class X {...}; X x; X y = x; b)Function Parameters void F( X ); ... X y; F( y ); c)Function Return Values X F() { X y; return y; }

C++ Object Model 7 of 19 Lecture 8 EECS 498 Winter 2000

Copy Constructors (cont.) In C++, copy constructor has form: X::X( X const &x ); Y::Y( Y const &y, inst stuff = 0);

When must copy constructor be synthesized? a)when class contains member with non-trivial copy constructor. b)when class is derived from base class with non-trivial copy constructor c)when the class declares (or inherits) virtual functions d)when the class is derived from a chain containing a virtual base class.

C++ Object Model 8 of 19 Lecture 8 EECS 498 Winter 2000 Semantics of Data

• Sizeof( Class ) is always > 0. • Static Data is placed in global storage class X { public: static int count; }; ... X foo( void ) { ... }; foo().count = 17; // -- Foo must be called! • Non-static data is positioned in order of declaration.

Offset of each member data is known at compile time.

Alignment factor may be required.

C++ Object Model 9 of 19 Lecture 8 EECS 498 Winter 2000

Data Layout without Polymorphism

Straightforward, except for alignment

class Concrete { private: int val; char c1, c2, c3; }; Assuming 4 byte integers, size = 8 bytes (4 + 3*1 + 1 for alignment) == 8 bytes.

Consider: class Concrete1 { int val; char c1 }; class Concrete2 : public Concrete1 { char c2}; class Concrete3 : public Concrete2 { char c3 };

Data content for Concrete == Concrete3. However Sizeof( Concrete3 ) = ((4 + 1 + 3) + (1 + 3) + (1 + 3)) == 16

C++ Object Model 10 of 19 Lecture 8 EECS 498 Winter 2000 Data Layout with Polymorphism

The virtual function table adds overhead to record size:

• Each Class has virtual function template • Each object has vptr referencing template • Class constructor modified to initialize vptr • Class destructor modified to support virtual destructors.

C++ Object Model 11 of 19 Lecture 8 EECS 498 Winter 2000

Multiple Inheritance class Point2d { float x virtual void foo(); float y float x, y; }; __vptr__Point2d

class Vertex { virtual void bar(); vertex *next Vertex *next; __vptr__Vertex };

class Vertex2d: float x public Point2d, public Vertex float y { __vptr__Point2d float z; }; vertex *next __vptr__Vertex Consider: Find vertex object in float z vertext2d, and Vertex2d v2d; construct address Vertex *pv; for sub-object reference pv = &v2d; assignment

C++ Object Model 12 of 19 Lecture 8 EECS 498 Winter 2000 Multiple - Virtual Inheritance In general, the most efficient use of a virtual base class is that of an abstract virtual base class with no associated data members.

class A { int i; }; class B : public virtual A { int x; }; class C : public virtual A { int y; }; class D : public B, public C { int z; }; There must be exactly 1 instance of A (and A::i) in D. How to implement? • Partition D into invariant and shared sections. Use latter to hold virtual base classes. How do you do this? a)Virtual Base Class Table (similar to VTble) (patented by Microsoft). b)Add VBClass offset to VTbl for class.

Notice that problems “goes away” if multiple inheritance is not supported.

C++ Object Model 13 of 19 Lecture 8 EECS 498 Winter 2000

Semantics of Functions

C++ classes have 3 types of functions: • static These are globally visible and do NOT require an instance of the object to invoke. (singleton, class factories, etc.) • non-static General methods of the class. They operate on data specific to an instance of an object.

This pointer is prepended to function parameter list. (Name manging & type-safe linkage). • virtual

Binding of abstraction to implementation is deferred until runtime. Location of function pointer to virtual function known at compile time.

C++ Object Model 14 of 19 Lecture 8 EECS 498 Winter 2000 Single Inheritance Chain with Virtual Functions

class Point type info for Point { mX public: Point::~Point() virtual ~Point(); __vptr__Point virtual Point& mult(float) = 0; pure_virtual_called() virtual float y() const {return 0;} Point virtual float z() const {return 0;} Point::y() private: float mX; Point::z() };

class Point2d : public Point { mX type info for Point2d public: ~Point2d(); __vptr__Point Point2d::~Point2d() Point2d& mult( float ); mY float y() const { return mY; } Point2d::mult(); private: float mY; Point2d Point2d::y() }; Point::z() class Point3d : public Point2d { public: mX ~Point3d(); type info for Point3d Point3d& mult( float ); __vptr__Point float z() const { return mZ; } Point3d::~Point3d() private: mY float mZ; Point3d::mult() }; mZ Point2d::y() Point3d Point3d::z()

C++ Object Model 15 of 19 Lecture 8 EECS 498 Winter 2000

Multiple Inheritance with Virtual Functions class Base1 type info for Base1 type info for Base2 { mBase1 Base1::~Base1() public: _vptr_Base1 Base2::~Base2() virtual ~Base1(); Base1::first() virtual void first(); Base2::second() virtual Base1* clone() const; Base1::clone() mBase2 private: Base2::clone() int mBase1; _vptr_Base2 };

class Base2 { public: type info for Derived virtual ~Base2(); mBase1 Derived::~Derived() virtual void second(); virtual Base2* clone() const; _vptr_Base1 Base1::first() private: int mBase2; mBase2 Derived::clone() }; _vptr_Base2 Base2::second() class Derived : mDerived public Base1, Shared Base1/Derived Table public Base2 { public: type info for Derived virtual ~Derived(); virtual Derived* clone() const; Derived::~Derived() private: Base2::second() int mDerived; } Derived::clone()

C++ Object Model 16 of 19 Lecture 8 EECS 498 Winter 2000 Function Lookup in & Java

C++ implementation of polymorphism is static: • Member functions for class are known at compile time. Efficient implementation; table index for function pointer. • Suffers from “binary compatibility” problem; Separate (later) compilation won’t link correctly to newer versions (if layout of structure has changed).

“Premature Binding” • “Binary Compatibility” is goal of COM

Both Smalltalk and Java resolve function binding at runtime • Dictionary (hash table?) lookup for function • “Delayed binding”; ablways (“Binary”) compatible

C++ Object Model 17 of 19 Lecture 8 EECS 498 Winter 2000

Semantics of Construction, Destruction & Copy

Without inheritance, semantics is straightforward. class Point { public: Point( x = 0.0, y = 0.0, z = 0.0 ) // -- non-trivial constructor : mX(x), mY(y), mZ(z) {} private: float mX, mY, mZ; };

Constructors need to be inserted at declaration points.

Point global ... void foo() { Point local; Point *heap = new Point; ...

C++ Object Model 18 of 19 Lecture 8 EECS 498 Winter 2000 Global and Locally Static Object

• Global objects are guaranteed to be constructed prior to the first user statement and destructed after the last user statement.

Calls to global object constructors are collected in the lexical ordering of the object in the file into a function which is invoked before main. Destructors are similarly handled, although the ordering is inverted. Cross file initialization order is not defined. • Static, local objects are initialized in their dynamic order of appearance. Destruction must mimic the reverse of this ordering. •

C++ Object Model 19 of 19 Lecture 8 EECS 498 Winter 2000