1 / 15

An anomaly of subtype relations at component refinement and a generative solution in C++

This paper discusses an anomaly in subtype relations at component refinement and presents a generative solution in C++. It explores topics such as virtual inheritance, intrusive implementation, traits, AOP, and more. The paper also includes code examples and comparisons with other approaches.

tara-kelley
Télécharger la présentation

An anomaly of subtype relations at component refinement and a generative solution in 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. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. An anomaly of subtype relations at component refinement and a generative solution in C++ Zoltán Porkoláb, István Zólyomi Eötvös Loránd University, Budapest, Hungary {gsd | scamel}@elte.hu

  2. Example (Harold Ossher) OpEval OpCheck OpDisplay Operator PlusEval PlusCheck PlusDisplay Plus

  3. 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 • are extensions to standard C++ • Signature • Promising, but non-standard, available only for Gnu compiler • Eiffel: ADOPT • CSet: subtype relationship implemented with metaprogramming • Non-intrusive solution based on the C++ standard

  4. C++ Templates • Macro-like type parameters • Strong type checking • Templates alone form a Turing-complete functional language inside C++ • Based on template specializations • Metaprograms • Executed during compilation • A program can observe its state • May make decisions depending on state • Compile-time adaptation

  5. CSET_3(OpDisplay, OpEval, OpCheck) op;

  6. Source code of Cset construction template <class List> struct CSet; template <class Head, class Tail> struct CSet< Typelist<Head,Tail> > : public Head, public CSet<Tail> { // --- Type name shortcuts typedef CSet<Tail> Rest; typedef CSet< Typelist<Head,Tail> > MyType; // --- Copy constructor CSet(const MyType& mt) : Head(mt), Rest(mt) {} // --- "Recursive" constructor CSet(const Head& head, const Rest& rest): Head(head), Rest(rest) {} }; template <class Head> struct CSet< Typelist<Head,NullType> > : public Head { // --- All in one constructor CSet(const Head& head) : Head(head) {} };

  7. Conversions between CSets • Initialize the head class for each recursion step • Template constructors provide conversion steps (the same for operator=) template <class Head, class Tail> template <class FromType> CSet< Typelist<Head,Tail> > :: CSet(const FromType& f): Head(f), CSet<Tail>(f) {} • Example of usage: CSET_3(PlusEval,PlusDisplay, PlusCheck) sum; CSET_2(OpEval,OpCheck) calculate; calculate = sum;

  8. Advantages • Type safe: based on builtin language conversions • Efficient: no temporal CSets or objects are used, objects are initialized directly • Open: not restricted to CSet only, any user object can be converted without explicit conversion call. struct Minus: public MinusEval, public MinusDisplay, public MinusCheck {}; Minus subtract; calculate = subtract;

  9. Smart pointers • Problems: • Conversion copies objects by value (slicing) • No dynamic binding • Solution: smart pointers • Implementation and usage similar to those of CSet CSET_3(PlusDisplay, PlusEval, PlusCheck) sum; CSETPTR_2(OpDisplay, OpEval) opPtr(sum); // --- Function call with explicit cast static_cast<OpDisplay*>(opPtr)->show(); // --- In longer form with implicit cast OpDisplay *displayPtr = opPtr; displayPtr->show();

  10. CSETPTR_1(OpEval) OpEval *head CSETPTR_2(OpDisplay,OpEval) OpDisplay *head CSETPTR_2(OpDisplay, OpEval) opPtr; points to head: OpDisplay* head: OpEval* points to PlusDisplay PlusCheck PlusEval

  11. CSetRef • Similar to CSetPtr • Store references instead of pointers • Consequences: • A CSetRef object must be initialized • Initializes by reference but copies by value during assignment CSET_3(PlusDisplay, PlusEval, PlusCheck) sum; // --- Initializes by reference CSETREF_3(OpDisplay, OpEval, OpCheck) exprRef(sum); // --- Copies by value exprRef = sum;

  12. #include <iostream> #include “cset.h" struct Shape { virtual void f() { std::cout <<"Shape"; } }; struct Circle : public Shape { void f() { std::cout <<"Circle"; } }; struct Colored {}; struct Filled {}; void main() { CSET_3(Circle,Colored, Filled) extCircle; CSET_3(Colored, Filled, Shape)extShape(extCircle); CSET_2(Filled, Colored)extensions(extCircle); extensions = extShape = extCircle; CSETPTR_3(Colored, Filled, Shape)extShapePtr(extCircle); Shape* shapePtr = extShapePtr; shapePtr->f(); // --- Prints “Circle” CSETPTR_3(Filled, Colored, Circle)extCirclePtr(extCircle); extShapePtr = extCircle; // --- Object -> Pointer extShapePtr = extCirclePtr; // --- Der. Pointer -> Base Pointer extShape = extShapePtr; // --- Pointer -> Object (by value) }

  13. Summary • Support for collaboration based design • Non-intrusive solution • Easy to understand and manage • No extension to standard C++ • Bad experience with compilers vs standards • Features: • Composition of concerns in a single class (CSet) • Conversion between related CSets • Dynamic binding with smart pointers and references

  14. gsd@elte.hu scamel@elte.hu Eötvös Loránd University, Budapest, Hungary Zoltán Porkoláb István Zólyomi Download source from http://gsd.web.elte.hu

More Related