Download presentation
Presentation is loading. Please wait.
Published byKristina Harriet Fletcher Modified over 9 years ago
1
1 An extension to the subtype relationship in C++ István Zólyomi, Zoltán Porkoláb and Tamás Kozsik {scamel | gsd | kto}@elte.hu Eötvös Loránd University, Budapest, Hungary
2
2 The structure of this presentation Motivation with examples Loki::Typelist (short reminder) Creating the Family hierarchy Converting between families Inclusion polymorphism (FamilyPtr and FamilyRef) Practical experiences Summary
3
3 Motivation Maximal separation of functionalities Collaboration based design oBetter maintenance of code oEasier to create classes with required behavior Create and handle classes as a collection of independent components
4
4 Vehicle TruckCar Emergency PoliceCar FireEngine EmergencyVehicle Example 1
5
5 ios iostream ostreamistream fstreambase ifstream ofstream fstream virtual
6
6 Possible solutions Virtual inheritance Intrusive: specified in base classes More concerns implies exponential number of virtual bases Traits No subtype relationship using hierarchies in traits AOP, MDSC, CF are for slightly different problems are extensions to standard C++ Families: subtype relationship implemented with metaprogramming Non-intrusive solution based on the C++ standard
7
7 Class: implementation of a concern –Orthogonal concerns in independent hierarchies Collaboration-based design: combining concerns –Collect concerns to gain required behavior Family: instrument to express collaboration of concerns –Implemented as a single class template –Collects concern classes as a mixin using multiple inheritance –OO languages support conversions to a single concern (base) –do not support conversions between families (collections of concerns) Terminology
8
8 OpEval PlusCheckPlusEval Operator Plus OpCheckOpDisplay PlusDisplay Example 2 (Harold Ossher)
9
9 Loki::Typelist Introduced by Andrei Alexandrescu (and others) Handles meta-information (types) in compile time like conventional containers do with data in runtime Any number of types can be listed using recursion struct Typelist { … }; The last element of every list is Loki::NullType by convention (like \0 for C-strings) typedef Typelist<char, Typelist<short, Typelist > > Scalars;
10
10 Typelist has many operations in Loki: appending, indexed access, removing duplicates, etc typedef TYPELIST_3(char,short,int) TheSameList; Loki::Typelist (cont.) We can make the previous class definition linear with predefined macros with NullType included typedef Append ::Result ExtendedList;
11
11 Source code of family construction template struct Family; template struct Family > : public Head, public Family { // --- Type name shortcuts typedef Family Rest; typedef Family > MyType; // --- Copy constructor Family(const MyType& mt) : Head(mt), Rest(mt) {} // --- "Recursive" constructor Family(const Head& head, const Rest& rest): Head(head), Rest(rest) {} }; template struct Family > : public Head { // --- All in one constructor Family(const Head& head) : Head(head) {} };
12
12 FAMILY_3(OpDisplay, OpEval, OpCheck) op;
13
13 Conversions between families Initialize the head class for each recursion step Template constructors provide conversion steps (the same for operator= ) FAMILY_3(PlusEval,PlusDisplay, PlusCheck) sum; FAMILY_2(OpEval,OpCheck) calculate; calculate = sum; Example of usage: template template Family > :: Family(const FromType& f): Head(f), Family (f) {}
14
14 Advantages Type safe: based on builtin language conversions Efficient: no temporal families or objects are used, objects are initialized directly General and transparent: not restricted to families only, any user object can be converted without explicit conversion call. struct Minus: public MinusEval, public MinusDisplay, public MinusCheck {}; Minus subtract; calculate = subtract;
15
15 Limitations No duplicates in typelists or compile error Keyword explicit is suppressed because of explicit constructor calls during conversion Compilation fails if there is no default or copy constructor and assignment operator
16
16 Smart pointers Problems: Conversion copies objects by value (slicing) No dynamic binding Solution: smart pointers Implementation and usage similar to those of Family FAMILY_3(PlusDisplay, PlusEval, PlusCheck) sum; FAMILYPTR_2(OpDisplay, OpEval) opPtr(sum); // --- Function call with explicit cast static_cast (opPtr)->show(); // --- In longer form with implicit cast OpDisplay *displayPtr = opPtr; displayPtr->show();
17
17 FAMILYPTR_2(OpDisplay,OpEval) OpDisplay *head FAMILYPTR_1(OpEval) OpEval *head PlusDisplayPlusCheckPlusEval points to FAMILYPTR_2(OpDisplay, OpEval) opPtr; head: OpDisplay* head: OpEval*
18
18 Similar to FamilyPtr Store references instead of pointers Consequences: A FamilyRef object must be initialized Initializes by reference but copies by value during assignment FamilyRef FAMILY_3(PlusDisplay, PlusEval, PlusCheck) sum; // --- Initializes by reference FAMILYREF_3(OpDisplay, OpEval, OpCheck) exprRef(sum); // --- Copies by value exprRef = sum;
19
19 #include #include "family.h" struct Shape { virtual void f() { std::cout << "Shape"; } }; struct Circle : public Shape { void f() { std::cout << "Circle"; } }; struct Colored {}; struct Filled {}; void main() { FAMILY_3(Circle, Colored, Filled) extCircle; FAMILY_3(Colored, Filled, Shape) extShape(extCircle); FAMILY_2(Filled, Colored) extensions(extCircle); extensions = extShape = extCircle; FAMILYPTR_3(Colored, Filled, Shape) extShapePtr(extCircle); Shape* shapePtr = extShapePtr; shapePtr->f(); // --- Prints “Circle” FAMILYPTR_3(Filled, Colored, Circle) extCirclePtr(extCircle); extShapePtr = extCircle;// --- Object -> Pointer extShapePtr = extCirclePtr; // --- Der. Pointer -> Base Pointer extShape = extShapePtr;// --- Pointer -> Object (by value) }
20
20 Experiences Compiler Nr. of classes Cause of limitation g++ 3.245 Macro parameter limit of precompiler g++ 2.9617Recursion depth limit reached Intel 7.125Unacceptable compile time VC++.NET0 Loki does not compile (compilers are not compliant to standards) Borland 6.00 OpenWatcom 1.00
21
21 Summary Support for collaboration based design Implementation uses Loki::Typelist Non-intrusive solution Easy to understand and manage No extension to C++ Bad experience with compilers vs standards Features: Composition of concerns in a single class (Family) Conversion between related families Dynamic binding with smart pointers and references
22
22 István Zólyomi Zoltán Porkoláb Tamás Kozsik Eötvös Loránd University, Budapest, Hungary scamel@elte.hu gsd@elte.hu kto@elte.hu Download source from http://gsd.web.elte.huhttp://gsd.web.elte.hu
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.