CS 242 History C++ � C+ + is an object-oriented extension of C � C was designed by Dennis Ritchie at Bell Labs • used to write Unix • based on BCPL John Mitchell � C+ + designed by Bjarne Stroustrup at Bell Labs • His original interest at Bell was research on simulation • Early extensions to C are based primarily on Simula • Called “C with classes” in early 1980’s • Popularity increased in late 1980’s and early 1990’s • Features were added incrementally Classes, templates, exceptions, multiple inheritance, type tests... Design Goals How successful? � Provide object-oriented features in C-based � Given the design goals and constraints, language, without compromising efficiency • this is a very well-designed language • Backwards compatibility with C � Many users -- tremendous popular success • Better static type checking � However, very complicated design • Data abstraction • Many specific properties with complex behavior • Objects and classes • Difficult to predict from basic principles • Prefer efficiency of compiled code where possible • Most serious users chose subset of language � Important principle – Full language is complex and unpredictable • If you do not use a feature, your compiled code • Many implementation-dependent properties should be as efficient as if the language did not • Language for adventure game fans include the feature. (compare to Smalltalk) Email discussion group comment Further evidence � Many style guides for using C+ + “safely” ... in my group ... we do use C+ + regularly and find � Every group I’ve ever talked to has established it very useful but certainly not perfect. Every full moon, however, we sacrifice a virgin disk to the some conventions and prohibitions among language gods in hopes that the True Object- themselves. Oriented Language will someday be manifest on • CORBA -- don’t inherit implementation earth, or at least on all major platforms. : -) • SGI compiler group -- no virtual functions • Others -- ??? Rick Pember, LLNL See Cargill’s book, etc. 1
Significant constraints Overview of C+ + � C has specific machine model � Additions and changes not related to objects • Access to underlying architecture • type bool � No garbage collection • pass-by -reference • user-defined overloading • Consistent with goal of efficiency • function templates • Need to manage object memory explicitly • … � Local variables stored in activation records • Objects treated as generalization of structs, so some objects may be allocated on stack • Stack/heap difference is visible to programmer C+ + Object System Some good decisions � Object-oriented features � Public, private, protected levels of visibility • Classes • Public: visible everywhere • Objects, with dynamic lookup of virtual functions • Protected: within class and subclass declarations • Inheritance • Private: visible only in class where declared – Single and multiple inheritance � Friend functions and classes – Public and private base classes • Careful attention to visibility and data abstraction • Subtyping � Allow inheritance without subtyping – Tied to inheritance mechanism • Better control of subtyping than without private base • Encapsulation classes Some problem areas Sample class: one-dimen. points � Casts class Pt { • Sometimes no-op, sometimes not (esp multiple inher) public: � Lack of garbage collection Pt(int xv); Overloaded constructor • Memory management is error prone Pt(Pt* pv ); – Constructors, destructors are helpful though � Objects allocated on stack int getX(); Public read access to private data • Better efficiency, interaction with exceptions virtual void move(int dx); Virtual function • BUT assignment works badly, possible dangling ptrs protected: � Overloading void setX(int xv); Protected write access • Too many code selection mechanisms private: � Multiple inheritance int x; Private member data • Efforts at efficiency lead to complicated behavior }; 2
Virtual functions Sample derived class Public base class gives supertype � Member functions are either class ColorPt: public Pt { public: • Virtual, if explicitly declared or inherited as virtual ColorPt(int xv,int c v ); • Non-virtual otherwise ColorPt(Pt* pv,int cv ); Overloaded constructor � Virtual members ColorPt(ColorPt* cp); • Are accessed by indirection through ptr in object int getColor(); Non-virtual function • May be redefined in derived (sub) classes virtual void move(int dx); Virtual functions � Non-virtual functions virtual void darken(int tint); protected: • Are called in the usual way. Just ordinary functions . void setColor(int cv ); Protected write access • Cannot redefine in derived classes (except overloading) private: � Pay overhead only if you use virtual functions int color; Private member data }; Run-time representation Compare to Smalltalk Point class Template Point object Point vtable Code for move Point object Method dictionary x vptr newX:Y: y x 3 2 ... ... 3 move ColorPoint object ColorPoint vtable Code for move ColorPoint class Template ColorPoint object vptr Method dictionary x x 5 newX:Y:C: Code for darken y c blue 4 color color 5 move red Data at same offset Function pointers at same offset Why is C+ + lookup simpler? Calls to virtual functions � Smalltalk has no static type system � One member function may call another class A { • Code p message:pars could refer to any object public: • Need to find method using pointer from object virtual int f (int x); • Different classes will put methods at different place in virtual int g(int y); method dictionary } ; � C+ + type gives compiler some superclass int A::f(int x) { … g(i) … ;} int A::g(int y) { … f(j) … ;} • Offset of data, fctn ptr same in subclass and superclass � How does body of f call the right g? • Offset of data and function ptr known at compile time • Code p-> move(x) compiles to equivalent of • If g is redefined in derived class B, then inherited f must call B::g (* (p-> vptr[ 1] ))(p,x) if m ove is first fctn in vtable. data passed to member function; see next slide 3
“This” pointer (analogous to self in Smalltalk) Non-virtual functions � Code is compiled so that member function takes � How is code for non-virtual function found? “object itself” as first argument � Same way as ordinary “non- member” functions: Code int A::f(int x) { … g(i) …;} • Compiler generates function code and assigns address compiled as int A::f(A * this, int x) { … this-> g(i) …;} • Address of code is placed in symbol table • At call site, address is taken from symbol table and placed in compiled code � “this” pointer may be used in member function • But some special scoping rules for classes • Can be used to return pointer to object itself, pass � Overloading pointer to object itself to another function, ... • Remember: overloading is resolved at compile time • This is different from run-time lookup of virtual function Scope rules in C+ + Virtual vs Overloaded Functions � Scope qualifiers class parent { public: void printclass() {printf("p ");} ; • binary :: operator, -> , and . virtual void printvirtual() {printf("p ");} ; } ; • class::member, ptr-> member, object.member class child : public parent { public: � A name outside a function or class, void printclass() {printf("c ");} ; • not prefixed by unary :: and not qualified refers to virtual void printvirtual() {printf("c ");} ; } ; global object, function, enumerator or type. main() { � A name after X::, ptr-> or obj. parent p; child c; parent * q; p.printclass(); p.printvirtual(); c.printclass(); c.printvirtual(); • where we assume ptr is pointer to class X and obj is an object of class X q = &p; q-> printclass(); q-> printvirtual(); q = &c; q-> printclass(); q-> printvirtual(); • refers to a member of class X or a base class of X } Output: p p c c p p p c Subtyping Independent classes not subtypes � Subtyping in principle class Point { class ColorPoint { public: public: • A < : B if every A object can be used without type int getX(); int getX(); error whenever a B object is required void move(int ); void move(int ); • Example: int getColor(); protected: ... Point: int getX(); void darken(int ); Public members private: ... void move(int ); protected: ... } ; ColorPoint : int getX(); private: ... int getColor(); } ; Public members void move(int ); � C+ + does not treat ColorPoint < : Point as written void darken(int tint); � C+ + : A < : B if class A has public base class B • Need public inheritance ColorPoint : public Pt • Why?? • This is weaker than necessary Why? 4
Recommend
More recommend